diff --git a/dotnet/samples/Concepts/ChatCompletion/AzureOpenAIWithData_ChatCompletion.cs b/dotnet/samples/Concepts/ChatCompletion/AzureOpenAIWithData_ChatCompletion.cs index dcfdf7b511f0..39ce395b27b7 100644 --- a/dotnet/samples/Concepts/ChatCompletion/AzureOpenAIWithData_ChatCompletion.cs +++ b/dotnet/samples/Concepts/ChatCompletion/AzureOpenAIWithData_ChatCompletion.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.OpenAI; +using Azure.AI.OpenAI.Chat; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; -using Microsoft.SemanticKernel.Connectors.OpenAI; +using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using xRetry; namespace ChatCompletion; @@ -47,8 +47,8 @@ public async Task ExampleWithChatCompletionAsync() chatHistory.AddUserMessage(ask); // Chat Completion example - var chatExtensionsOptions = GetAzureChatExtensionsOptions(); - var promptExecutionSettings = new OpenAIPromptExecutionSettings { AzureChatExtensionsOptions = chatExtensionsOptions }; + var dataSource = GetAzureSearchDataSource(); + var promptExecutionSettings = new AzureOpenAIPromptExecutionSettings { AzureChatDataSource = dataSource }; var chatCompletion = kernel.GetRequiredService(); @@ -98,8 +98,8 @@ public async Task ExampleWithKernelAsync() var function = kernel.CreateFunctionFromPrompt("Question: {{$input}}"); - var chatExtensionsOptions = GetAzureChatExtensionsOptions(); - var promptExecutionSettings = new OpenAIPromptExecutionSettings { AzureChatExtensionsOptions = chatExtensionsOptions }; + var dataSource = GetAzureSearchDataSource(); + var promptExecutionSettings = new AzureOpenAIPromptExecutionSettings { AzureChatDataSource = dataSource }; // First question without previous context based on uploaded content. var response = await kernel.InvokeAsync(function, new(promptExecutionSettings) { ["input"] = ask }); @@ -125,20 +125,15 @@ public async Task ExampleWithKernelAsync() } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - private static AzureChatExtensionsOptions GetAzureChatExtensionsOptions() + private static AzureSearchChatDataSource GetAzureSearchDataSource() { - var azureSearchExtensionConfiguration = new AzureSearchChatExtensionConfiguration + return new AzureSearchChatDataSource { - SearchEndpoint = new Uri(TestConfiguration.AzureAISearch.Endpoint), - Authentication = new OnYourDataApiKeyAuthenticationOptions(TestConfiguration.AzureAISearch.ApiKey), + Endpoint = new Uri(TestConfiguration.AzureAISearch.Endpoint), + Authentication = DataSourceAuthentication.FromApiKey(TestConfiguration.AzureAISearch.ApiKey), IndexName = TestConfiguration.AzureAISearch.IndexName }; - - return new AzureChatExtensionsOptions - { - Extensions = { azureSearchExtensionConfiguration } - }; } } diff --git a/dotnet/samples/Concepts/ChatCompletion/ChatHistoryAuthorName.cs b/dotnet/samples/Concepts/ChatCompletion/ChatHistoryAuthorName.cs index 05346974da2f..2d08c507aa4c 100644 --- a/dotnet/samples/Concepts/ChatCompletion/ChatHistoryAuthorName.cs +++ b/dotnet/samples/Concepts/ChatCompletion/ChatHistoryAuthorName.cs @@ -2,6 +2,7 @@ using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; +using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using Microsoft.SemanticKernel.Connectors.OpenAI; namespace ChatCompletion; diff --git a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletion.cs b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletion.cs index 22b6eec9baaf..758af2acc389 100644 --- a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletion.cs +++ b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletion.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using Microsoft.SemanticKernel.ChatCompletion; +using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using Microsoft.SemanticKernel.Connectors.OpenAI; namespace ChatCompletion; diff --git a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionMultipleChoices.cs b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionMultipleChoices.cs deleted file mode 100644 index 9534cac09a63..000000000000 --- a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionMultipleChoices.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.ChatCompletion; -using Microsoft.SemanticKernel.Connectors.OpenAI; - -namespace ChatCompletion; - -/// -/// The following example shows how to use Semantic Kernel with multiple chat completion results. -/// -public class OpenAI_ChatCompletionMultipleChoices(ITestOutputHelper output) : BaseTest(output) -{ - /// - /// Example with multiple chat completion results using . - /// - [Fact] - public async Task MultipleChatCompletionResultsUsingKernelAsync() - { - var kernel = Kernel - .CreateBuilder() - .AddOpenAIChatCompletion( - modelId: TestConfiguration.OpenAI.ChatModelId, - apiKey: TestConfiguration.OpenAI.ApiKey) - .Build(); - - // Execution settings with configured ResultsPerPrompt property. - var executionSettings = new OpenAIPromptExecutionSettings { MaxTokens = 200, ResultsPerPrompt = 3 }; - - var contents = await kernel.InvokePromptAsync>("Write a paragraph about why AI is awesome", new(executionSettings)); - - foreach (var content in contents!) - { - Console.Write(content.ToString() ?? string.Empty); - Console.WriteLine("\n-------------\n"); - } - } - - /// - /// Example with multiple chat completion results using . - /// - [Fact] - public async Task MultipleChatCompletionResultsUsingChatCompletionServiceAsync() - { - var kernel = Kernel - .CreateBuilder() - .AddOpenAIChatCompletion( - modelId: TestConfiguration.OpenAI.ChatModelId, - apiKey: TestConfiguration.OpenAI.ApiKey) - .Build(); - - // Execution settings with configured ResultsPerPrompt property. - var executionSettings = new OpenAIPromptExecutionSettings { MaxTokens = 200, ResultsPerPrompt = 3 }; - - var chatHistory = new ChatHistory(); - chatHistory.AddUserMessage("Write a paragraph about why AI is awesome"); - - var chatCompletionService = kernel.GetRequiredService(); - - foreach (var chatMessageContent in await chatCompletionService.GetChatMessageContentsAsync(chatHistory, executionSettings)) - { - Console.Write(chatMessageContent.Content ?? string.Empty); - Console.WriteLine("\n-------------\n"); - } - } - - /// - /// This example shows how to handle multiple results in case if prompt template contains a call to another prompt function. - /// is used for result selection. - /// - [Fact] - public async Task MultipleChatCompletionResultsInPromptTemplateAsync() - { - var kernel = Kernel - .CreateBuilder() - .AddOpenAIChatCompletion( - modelId: TestConfiguration.OpenAI.ChatModelId, - apiKey: TestConfiguration.OpenAI.ApiKey) - .Build(); - - var executionSettings = new OpenAIPromptExecutionSettings { MaxTokens = 200, ResultsPerPrompt = 3 }; - - // Initializing a function with execution settings for multiple results. - // We ask AI to write one paragraph, but in execution settings we specified that we want 3 different results for this request. - var function = KernelFunctionFactory.CreateFromPrompt("Write a paragraph about why AI is awesome", executionSettings, "GetParagraph"); - var plugin = KernelPluginFactory.CreateFromFunctions("MyPlugin", [function]); - - kernel.Plugins.Add(plugin); - - // Add function result selection filter. - kernel.FunctionInvocationFilters.Add(new FunctionResultSelectionFilter(this.Output)); - - // Inside our main request, we call MyPlugin.GetParagraph function for text summarization. - // Taking into account that MyPlugin.GetParagraph function produces 3 results, for text summarization we need to choose only one of them. - // Registered filter will be invoked during execution, which will select and return only 1 result, and this result will be inserted in our main request for summarization. - var result = await kernel.InvokePromptAsync("Summarize this text: {{MyPlugin.GetParagraph}}"); - - // It's possible to check what prompt was rendered for our main request. - Console.WriteLine($"Rendered prompt: '{result.RenderedPrompt}'"); - - // Output: - // Rendered prompt: 'Summarize this text: AI is awesome because...' - } - - /// - /// Example of filter which is responsible for result selection in case if some function produces multiple results. - /// - private sealed class FunctionResultSelectionFilter(ITestOutputHelper output) : IFunctionInvocationFilter - { - public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func next) - { - await next(context); - - // Selection logic for function which is expected to produce multiple results. - if (context.Function.Name == "GetParagraph") - { - // Get multiple results from function invocation - var contents = context.Result.GetValue>()!; - - output.WriteLine("Multiple results:"); - - foreach (var content in contents) - { - output.WriteLine(content.ToString()); - } - - // Select first result for correct prompt rendering - var selectedContent = contents[0]; - context.Result = new FunctionResult(context.Function, selectedContent, context.Kernel.Culture, selectedContent.Metadata); - } - } - } -} diff --git a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreaming.cs b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreaming.cs index 4836dcf03d9f..bd1285e29af3 100644 --- a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreaming.cs +++ b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreaming.cs @@ -2,6 +2,7 @@ using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; +using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using Microsoft.SemanticKernel.Connectors.OpenAI; namespace ChatCompletion; diff --git a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreamingMultipleChoices.cs b/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreamingMultipleChoices.cs deleted file mode 100644 index 6a23a43ae9f8..000000000000 --- a/dotnet/samples/Concepts/ChatCompletion/OpenAI_ChatCompletionStreamingMultipleChoices.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.ChatCompletion; -using Microsoft.SemanticKernel.Connectors.OpenAI; - -namespace ChatCompletion; - -// The following example shows how to use Semantic Kernel with multiple streaming chat completion results. -public class OpenAI_ChatCompletionStreamingMultipleChoices(ITestOutputHelper output) : BaseTest(output) -{ - [Fact] - public Task AzureOpenAIMultiStreamingChatCompletionAsync() - { - Console.WriteLine("======== Azure OpenAI - Multiple Chat Completions - Raw Streaming ========"); - - AzureOpenAIChatCompletionService chatCompletionService = new( - deploymentName: TestConfiguration.AzureOpenAI.ChatDeploymentName, - endpoint: TestConfiguration.AzureOpenAI.Endpoint, - apiKey: TestConfiguration.AzureOpenAI.ApiKey, - modelId: TestConfiguration.AzureOpenAI.ChatModelId); - - return StreamingChatCompletionAsync(chatCompletionService, 3); - } - - [Fact] - public Task OpenAIMultiStreamingChatCompletionAsync() - { - Console.WriteLine("======== OpenAI - Multiple Chat Completions - Raw Streaming ========"); - - OpenAIChatCompletionService chatCompletionService = new( - modelId: TestConfiguration.OpenAI.ChatModelId, - apiKey: TestConfiguration.OpenAI.ApiKey); - - return StreamingChatCompletionAsync(chatCompletionService, 3); - } - - /// - /// Streams the results of a chat completion request to the console. - /// - /// Chat completion service to use - /// Number of results to get for each chat completion request - private async Task StreamingChatCompletionAsync(IChatCompletionService chatCompletionService, - int numResultsPerPrompt) - { - var executionSettings = new OpenAIPromptExecutionSettings() - { - MaxTokens = 200, - FrequencyPenalty = 0, - PresencePenalty = 0, - Temperature = 1, - TopP = 0.5, - ResultsPerPrompt = numResultsPerPrompt - }; - - var consoleLinesPerResult = 10; - - // Uncomment this if you want to use a console app to display the results - // ClearDisplayByAddingEmptyLines(); - - var prompt = "Hi, I'm looking for 5 random title names for sci-fi books"; - - await ProcessStreamAsyncEnumerableAsync(chatCompletionService, prompt, executionSettings, consoleLinesPerResult); - - Console.WriteLine(); - - // Set cursor position to after displayed results - // Console.SetCursorPosition(0, executionSettings.ResultsPerPrompt * consoleLinesPerResult); - - Console.WriteLine(); - } - - /// - /// Does the actual streaming and display of the chat completion. - /// - private async Task ProcessStreamAsyncEnumerableAsync(IChatCompletionService chatCompletionService, string prompt, - OpenAIPromptExecutionSettings executionSettings, int consoleLinesPerResult) - { - var messagesPerChoice = new Dictionary(); - var chatHistory = new ChatHistory(prompt); - - // For each chat completion update - await foreach (StreamingChatMessageContent chatUpdate in chatCompletionService.GetStreamingChatMessageContentsAsync(chatHistory, executionSettings)) - { - // Set cursor position to the beginning of where this choice (i.e. this result of - // a single multi-result request) is to be displayed. - // Console.SetCursorPosition(0, chatUpdate.ChoiceIndex * consoleLinesPerResult + 1); - - // The first time around, start choice text with role information - if (!messagesPerChoice.ContainsKey(chatUpdate.ChoiceIndex)) - { - messagesPerChoice[chatUpdate.ChoiceIndex] = $"Role: {chatUpdate.Role ?? new AuthorRole()}\n"; - Console.Write($"Choice index: {chatUpdate.ChoiceIndex}, Role: {chatUpdate.Role ?? new AuthorRole()}"); - } - - // Add latest completion bit, if any - if (chatUpdate.Content is { Length: > 0 }) - { - messagesPerChoice[chatUpdate.ChoiceIndex] += chatUpdate.Content; - } - - // Overwrite what is currently in the console area for the updated choice - // Console.Write(messagesPerChoice[chatUpdate.ChoiceIndex]); - Console.Write($"Choice index: {chatUpdate.ChoiceIndex}, Content: {chatUpdate.Content}"); - } - - // Display the aggregated results - foreach (string message in messagesPerChoice.Values) - { - Console.WriteLine("-------------------"); - Console.WriteLine(message); - } - } -} diff --git a/dotnet/samples/Concepts/ChatCompletion/OpenAI_CustomAzureOpenAIClient.cs b/dotnet/samples/Concepts/ChatCompletion/OpenAI_CustomAzureOpenAIClient.cs index 9e63e4b46975..64228f692799 100644 --- a/dotnet/samples/Concepts/ChatCompletion/OpenAI_CustomAzureOpenAIClient.cs +++ b/dotnet/samples/Concepts/ChatCompletion/OpenAI_CustomAzureOpenAIClient.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. +using System.ClientModel.Primitives; using Azure; using Azure.AI.OpenAI; -using Azure.Core.Pipeline; using Microsoft.SemanticKernel; namespace ChatCompletion; @@ -28,12 +28,12 @@ public async Task RunAsync() var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("My-Custom-Header", "My Custom Value"); - // Configure OpenAIClient to use the customized HttpClient - var clientOptions = new OpenAIClientOptions + // Configure AzureOpenAIClient to use the customized HttpClient + var clientOptions = new AzureOpenAIClientOptions { - Transport = new HttpClientTransport(httpClient), + Transport = new HttpClientPipelineTransport(httpClient), }; - var openAIClient = new OpenAIClient(new Uri(endpoint), new AzureKeyCredential(apiKey), clientOptions); + var openAIClient = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(apiKey), clientOptions); IKernelBuilder builder = Kernel.CreateBuilder(); builder.AddAzureOpenAIChatCompletion(deploymentName, openAIClient); diff --git a/dotnet/samples/Concepts/Concepts.csproj b/dotnet/samples/Concepts/Concepts.csproj index fd06e4a0dc25..666b84f0cf6d 100644 --- a/dotnet/samples/Concepts/Concepts.csproj +++ b/dotnet/samples/Concepts/Concepts.csproj @@ -126,47 +126,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -185,46 +144,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dotnet/samples/Concepts/Planners/AutoFunctionCallingPlanning.cs b/dotnet/samples/Concepts/Planners/AutoFunctionCallingPlanning.cs index 4c287a63a216..38e3e53a0e74 100644 --- a/dotnet/samples/Concepts/Planners/AutoFunctionCallingPlanning.cs +++ b/dotnet/samples/Concepts/Planners/AutoFunctionCallingPlanning.cs @@ -7,13 +7,13 @@ using System.Security.Cryptography; using System.Text; using System.Text.Json; -using Azure.AI.OpenAI; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.OpenAI; using Microsoft.SemanticKernel.Planning; +using OpenAI.Chat; namespace Planners; @@ -328,7 +328,7 @@ private int GetChatHistoryTokens(ChatHistory? chatHistory) { if (message.Metadata is not null && message.Metadata.TryGetValue("Usage", out object? usage) && - usage is CompletionsUsage completionsUsage && + usage is ChatTokenUsage completionsUsage && completionsUsage is not null) { tokens += completionsUsage.TotalTokens; diff --git a/dotnet/samples/Concepts/TextGeneration/OpenAI_TextGenerationStreaming.cs b/dotnet/samples/Concepts/TextGeneration/OpenAI_TextGenerationStreaming.cs index 44b7806a1355..bb906bb6d05c 100644 --- a/dotnet/samples/Concepts/TextGeneration/OpenAI_TextGenerationStreaming.cs +++ b/dotnet/samples/Concepts/TextGeneration/OpenAI_TextGenerationStreaming.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. +using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using Microsoft.SemanticKernel.Connectors.OpenAI; using Microsoft.SemanticKernel.TextGeneration; @@ -22,11 +23,11 @@ public Task AzureOpenAITextGenerationStreamAsync() { Console.WriteLine("======== Azure OpenAI - Text Generation - Raw Streaming ========"); - var textGeneration = new AzureOpenAITextGenerationService( - deploymentName: TestConfiguration.AzureOpenAI.DeploymentName, + var textGeneration = new AzureOpenAIChatCompletionService( + deploymentName: TestConfiguration.AzureOpenAI.ChatDeploymentName, endpoint: TestConfiguration.AzureOpenAI.Endpoint, apiKey: TestConfiguration.AzureOpenAI.ApiKey, - modelId: TestConfiguration.AzureOpenAI.ModelId); + modelId: TestConfiguration.AzureOpenAI.ChatModelId); return this.TextGenerationStreamAsync(textGeneration); } @@ -36,7 +37,7 @@ public Task OpenAITextGenerationStreamAsync() { Console.WriteLine("======== Open AI - Text Generation - Raw Streaming ========"); - var textGeneration = new OpenAITextGenerationService("gpt-3.5-turbo-instruct", TestConfiguration.OpenAI.ApiKey); + var textGeneration = new OpenAIChatCompletionService(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey); return this.TextGenerationStreamAsync(textGeneration); } diff --git a/dotnet/samples/Demos/StepwisePlannerMigration/StepwisePlannerMigration.csproj b/dotnet/samples/Demos/StepwisePlannerMigration/StepwisePlannerMigration.csproj index 1475397e7eb2..adeeb1f6471b 100644 --- a/dotnet/samples/Demos/StepwisePlannerMigration/StepwisePlannerMigration.csproj +++ b/dotnet/samples/Demos/StepwisePlannerMigration/StepwisePlannerMigration.csproj @@ -9,7 +9,7 @@ - + diff --git a/dotnet/src/Connectors/Connectors.OpenAIV2.UnitTests/Services/OpenAITextToImageServiceTests.cs b/dotnet/src/Connectors/Connectors.OpenAIV2.UnitTests/Services/OpenAITextToImageServiceTests.cs index f59fea554eda..1528986b9064 100644 --- a/dotnet/src/Connectors/Connectors.OpenAIV2.UnitTests/Services/OpenAITextToImageServiceTests.cs +++ b/dotnet/src/Connectors/Connectors.OpenAIV2.UnitTests/Services/OpenAITextToImageServiceTests.cs @@ -46,15 +46,6 @@ public void ConstructorWorksCorrectly() Assert.Equal("model", sut.Attributes[AIServiceExtensions.ModelIdKey]); } - [Fact] - public void ItThrowsIfModelIdIsNotProvided() - { - // Act & Assert - Assert.Throws(() => new OpenAITextToImageService("apikey", modelId: " ")); - Assert.Throws(() => new OpenAITextToImageService("apikey", modelId: string.Empty)); - Assert.Throws(() => new OpenAITextToImageService("apikey", modelId: null!)); - } - [Theory] [InlineData(256, 256, "dall-e-2")] [InlineData(512, 512, "dall-e-2")] diff --git a/dotnet/src/Connectors/Connectors.OpenAIV2/Core/ClientCore.TextToImage.cs b/dotnet/src/Connectors/Connectors.OpenAIV2/Core/ClientCore.TextToImage.cs index 26d8480fd004..cb6a681ca0e1 100644 --- a/dotnet/src/Connectors/Connectors.OpenAIV2/Core/ClientCore.TextToImage.cs +++ b/dotnet/src/Connectors/Connectors.OpenAIV2/Core/ClientCore.TextToImage.cs @@ -45,7 +45,11 @@ internal async Task GenerateImageAsync( ResponseFormat = GeneratedImageFormat.Uri }; - ClientResult response = await RunRequestAsync(() => this.Client.GetImageClient(this.ModelId).GenerateImageAsync(prompt, imageOptions, cancellationToken)).ConfigureAwait(false); + // The model is not required by the OpenAI API and defaults to the DALL-E 2 server-side - https://platform.openai.com/docs/api-reference/images/create#images-create-model. + // However, considering that the model is required by the OpenAI SDK and the ModelId property is optional, it defaults to DALL-E 2 in the line below. + var model = string.IsNullOrEmpty(this.ModelId) ? "dall-e-2" : this.ModelId; + + ClientResult response = await RunRequestAsync(() => this.Client.GetImageClient(model).GenerateImageAsync(prompt, imageOptions, cancellationToken)).ConfigureAwait(false); var generatedImage = response.Value; return generatedImage.ImageUri?.ToString() ?? throw new KernelException("The generated image is not in url format"); diff --git a/dotnet/src/Connectors/Connectors.OpenAIV2/Services/OpenAITextToImageService.cs b/dotnet/src/Connectors/Connectors.OpenAIV2/Services/OpenAITextToImageService.cs index cca9073bfe9c..5bbff66c761e 100644 --- a/dotnet/src/Connectors/Connectors.OpenAIV2/Services/OpenAITextToImageService.cs +++ b/dotnet/src/Connectors/Connectors.OpenAIV2/Services/OpenAITextToImageService.cs @@ -50,7 +50,6 @@ public OpenAITextToImageService( HttpClient? httpClient = null, ILoggerFactory? loggerFactory = null) { - Verify.NotNullOrWhiteSpace(modelId, nameof(modelId)); this._client = new(modelId, apiKey, organization, null, httpClient, loggerFactory?.CreateLogger(this.GetType())); } diff --git a/dotnet/src/IntegrationTestsV2/Connectors/OpenAI/OpenAITextToImageTests.cs b/dotnet/src/IntegrationTestsV2/Connectors/OpenAI/OpenAITextToImageTests.cs index b2addba05188..85512760dcd0 100644 --- a/dotnet/src/IntegrationTestsV2/Connectors/OpenAI/OpenAITextToImageTests.cs +++ b/dotnet/src/IntegrationTestsV2/Connectors/OpenAI/OpenAITextToImageTests.cs @@ -39,4 +39,25 @@ public async Task OpenAITextToImageByModelTestAsync(string modelId, int width, i Assert.NotNull(result); Assert.NotEmpty(result); } + + [Fact] + public async Task OpenAITextToImageUseDallE2ByDefaultAsync() + { + // Arrange + OpenAIConfiguration? openAIConfiguration = this._configuration.GetSection("OpenAITextToImage").Get(); + Assert.NotNull(openAIConfiguration); + + var kernel = Kernel.CreateBuilder() + .AddOpenAITextToImage(apiKey: openAIConfiguration.ApiKey, modelId: null) + .Build(); + + var service = kernel.GetRequiredService(); + + // Act + var result = await service.GenerateImageAsync("The sun rises in the east and sets in the west.", 256, 256); + + // Assert + Assert.NotNull(result); + Assert.NotEmpty(result); + } }