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: Improve the ITextToImageService abstractions to support ExecutionSettings #8068

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1f567f3
Improving the ITextToImageService to support ExecutionSettings, Image…
RogerBarreto Aug 9, 2024
0af318e
Merge branch 'microsoft:main' into issues/5657-itexttoimage-update
RogerBarreto Aug 12, 2024
201423b
Add quality and style to TextToImageRequest
aghimir3 Aug 14, 2024
6895c05
Implement GetImageContentsAsync in OpenAITextToImageService
aghimir3 Aug 14, 2024
ef12678
Add unit tests for GetImageContentsAsync method
aghimir3 Aug 14, 2024
9a47d7c
Merge pull request #4 from aghimir3/issues/5657-itexttoimage-ag
RogerBarreto Aug 14, 2024
f58e689
Merge branch 'main' of https://github.com/microsoft/semantic-kernel i…
RogerBarreto Sep 13, 2024
36d4fb9
Adding support for Text-To-Image Settings
RogerBarreto Sep 13, 2024
b9e40b4
Removed unecessary parameter
RogerBarreto Sep 13, 2024
23e2f03
Fix Warnings
RogerBarreto Sep 16, 2024
3e0c967
Add missing xmldocs and small changes
RogerBarreto Sep 16, 2024
e7f87eb
Merge branch 'main' into issues/5657-itexttoimage-update
RogerBarreto Sep 20, 2024
17c1492
GenerateImage extension method UT working
RogerBarreto Sep 23, 2024
2141016
Updating ITs
RogerBarreto Sep 23, 2024
dc7f8ef
Address extra folder
RogerBarreto Sep 23, 2024
373870e
Fix warnings
RogerBarreto Sep 24, 2024
de0c4f2
Fix warnings
RogerBarreto Sep 24, 2024
a783563
Update Obsolete Concepts
RogerBarreto Sep 24, 2024
34da6a7
Fix warning
RogerBarreto Sep 24, 2024
7f5ec3b
Merge branch 'main' of https://github.com/microsoft/semantic-kernel i…
RogerBarreto Sep 27, 2024
f0c95cd
Adding suppressions were needed
RogerBarreto Sep 27, 2024
1681cd4
Merge branch 'main' into issues/5657-itexttoimage-update
RogerBarreto Sep 27, 2024
e2177c4
Merge branch 'main' into issues/5657-itexttoimage-update
RogerBarreto Sep 30, 2024
31b6d8c
Address PR comments
RogerBarreto Sep 30, 2024
3ea6fab
Address UT and IT
RogerBarreto Sep 30, 2024
af81e60
Adding extension method usage concepts
RogerBarreto Sep 30, 2024
a459d54
Adding missing MS header
RogerBarreto Sep 30, 2024
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
184 changes: 184 additions & 0 deletions dotnet/samples/Concepts/TextToImage/OpenAI_TextToImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Copyright (c) Microsoft. All rights reserved.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http.Resilience;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.TextToImage;

namespace TextToImage;

// The following example shows how to use Semantic Kernel with OpenAI DALL-E 2 to create images
public class OpenAI_TextToImage(ITestOutputHelper output) : BaseTest(output)
{
[Fact]
public async Task OpenAIDallE2Async()
{
Console.WriteLine("======== OpenAI DALL-E 2 Text To Image ========");

Kernel kernel = Kernel.CreateBuilder()
.AddOpenAITextToImage(TestConfiguration.OpenAI.ApiKey) // Add your text to image service
.AddOpenAIChatCompletion(TestConfiguration.OpenAI.ChatModelId, TestConfiguration.OpenAI.ApiKey) // Add your chat completion service
.Build();

ITextToImageService dallE = kernel.GetRequiredService<ITextToImageService>();

var imageDescription = "A cute baby sea otter";
var images = await dallE.GetImageContentsAsync(imageDescription, new OpenAITextToImageExecutionSettings { Size = (256, 256) });
var image = images[0].Uri!.ToString();
Console.WriteLine(imageDescription);
Console.WriteLine("Image URL: " + image);

/* Output:

A cute baby sea otter
Image URL: https://oaidalleapiprodscus.blob.core.windows.net/private/....

*/

Console.WriteLine("======== Chat with images ========");

var chatGPT = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory(
"You're chatting with a user. Instead of replying directly to the user" +
" provide the description of an image that expresses what you want to say." +
" The user won't see your message, they will see only the image. The system " +
" generates an image using your description, so it's important you describe the image with details.");

var msg = "Hi, I'm from Tokyo, where are you from?";
chatHistory.AddUserMessage(msg);
Console.WriteLine("User: " + msg);

var reply = await chatGPT.GetChatMessageContentAsync(chatHistory);
chatHistory.Add(reply);
images = await dallE.GetImageContentsAsync(reply.Content!, new OpenAITextToImageExecutionSettings { Size = (256, 256) });
image = images[0].Uri!.ToString();
Console.WriteLine("Bot: " + image);
Console.WriteLine("Img description: " + reply);

msg = "Oh, wow. Not sure where that is, could you provide more details?";
chatHistory.AddUserMessage(msg);
Console.WriteLine("User: " + msg);

reply = await chatGPT.GetChatMessageContentAsync(chatHistory);
chatHistory.Add(reply);
images = await dallE.GetImageContentsAsync(reply.Content!, new OpenAITextToImageExecutionSettings { Size = (256, 256) });
image = images[0].Uri!.ToString();
Console.WriteLine("Bot: " + image);
Console.WriteLine("Img description: " + reply);

/* Output:

User: Hi, I'm from Tokyo, where are you from?
Bot: https://oaidalleapiprodscus.blob.core.windows.net/private/...
Img description: [An image of a globe with a pin dropped on a location in the middle of the ocean]

User: Oh, wow. Not sure where that is, could you provide more details?
Bot: https://oaidalleapiprodscus.blob.core.windows.net/private/...
Img description: [An image of a map zooming in on the pin location, revealing a small island with a palm tree on it]

*/
}

[Fact]
public async Task SimpleTextToImageExampleAsync()
{
var builder = Kernel.CreateBuilder()
.AddAzureOpenAITextToImage( // Add your text to image service
deploymentName: TestConfiguration.AzureOpenAI.ImageDeploymentName,
endpoint: TestConfiguration.AzureOpenAI.ImageEndpoint,
apiKey: TestConfiguration.AzureOpenAI.ImageApiKey,
modelId: TestConfiguration.AzureOpenAI.ImageModelId);

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

var generatedImages = await service.GetImageContentsAsync(new TextContent("A cute baby sea otter"), new OpenAITextToImageExecutionSettings { Size = (Width: 1792, Height: 1024) });

this.Output.WriteLine(generatedImages[0].Uri!.ToString());
}

[Fact]
public async Task OpenAIDallE3Async()
{
Console.WriteLine("======== OpenAI DALL-E 3 Text To Image ========");

var builder = Kernel.CreateBuilder()
.AddOpenAITextToImage( // Add your text to image service
modelId: "dall-e-3",
apiKey: TestConfiguration.OpenAI.ApiKey) //DALL-E 3 is only supported in this version
.AddOpenAIChatCompletion( // Add your chat completion service
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);

builder.Services.ConfigureHttpClientDefaults(c =>
{
// Use a standard resiliency policy, augmented to retry 5 times
c.AddStandardResilienceHandler().Configure(o =>
{
o.Retry.MaxRetryAttempts = 5;
o.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(120);
});
});

var kernel = builder.Build();

ITextToImageService dallE = kernel.GetRequiredService<ITextToImageService>();
var imageDescription = "A cute baby sea otter";
var images = await dallE.GetImageContentsAsync(imageDescription, new OpenAITextToImageExecutionSettings { Size = (1024, 1024) });

Console.WriteLine(imageDescription);
Console.WriteLine("Image URL: " + images[0].Uri!);

/* Output:

A cute baby sea otter
Image URL: https://oaidalleapiprodscus.blob.core.windows.net/private/org-/....

*/

Console.WriteLine("======== Chat with images ========");

var chatGPT = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory(
"You're chatting with a user. Instead of replying directly to the user" +
" provide the description of an image that expresses what you want to say." +
" The user won't see your message, they will see only the image. The system " +
" generates an image using your description, so it's important you describe the image with details.");

var msg = "Hi, I'm from Tokyo, where are you from?";
chatHistory.AddUserMessage(msg);
Console.WriteLine("User: " + msg);

var reply = await chatGPT.GetChatMessageContentAsync(chatHistory);
chatHistory.Add(reply);
images = await dallE.GetImageContentsAsync(reply.Content!, new OpenAITextToImageExecutionSettings { Size = (1024, 1024) });
var image = images[0].Uri!.ToString();
Console.WriteLine("Bot: " + image);
Console.WriteLine("Img description: " + reply);

msg = "Oh, wow. Not sure where that is, could you provide more details?";
chatHistory.AddUserMessage(msg);
Console.WriteLine("User: " + msg);

reply = await chatGPT.GetChatMessageContentAsync(chatHistory);
chatHistory.Add(reply);
images = await dallE.GetImageContentsAsync(reply.Content!, new OpenAITextToImageExecutionSettings { Size = (1024, 1024) });
image = images[0].Uri!.ToString();
Console.WriteLine("Bot: " + image);
Console.WriteLine("Img description: " + reply);

/* Output:

User: Hi, I'm from Tokyo, where are you from?
Bot: https://dalleproduse.blob.core.windows.net/private/images/......
Img description: [An image of a globe with a pin dropped on a location in the middle of the ocean]

User: Oh, wow. Not sure where that is, could you provide more details?
Bot: https://dalleproduse.blob.core.windows.net/private/images/......
Img description: [An image of a map zooming in on the pin location, revealing a small island with a palm tree on it]

*/
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

namespace TextToImage;

// The following example shows how to use Semantic Kernel with OpenAI DALL-E 2 to create images
public class OpenAI_TextToImageDalle3(ITestOutputHelper output) : BaseTest(output)
/// <summary>
/// The following example shows how you can still use the previous "ITextToImageService.GenerateImageAsync" API to generate images.
/// </summary>
public class OpenAI_TextToImageLegacy(ITestOutputHelper output) : BaseTest(output)
{
[Fact]
public async Task OpenAIDallEAsync()
Expand Down
Loading
Loading