diff --git a/api/OpenAI.net8.0.cs b/api/OpenAI.net8.0.cs index c72dc3873..a68247f1b 100644 --- a/api/OpenAI.net8.0.cs +++ b/api/OpenAI.net8.0.cs @@ -44,6 +44,7 @@ public class OpenAIClientOptions : ClientPipelineOptions { public string ProjectId { get; set; } public string UserAgentApplicationId { get; set; } } + [Experimental("OPENAI001")] public class OpenAIContext : ModelReaderWriterContext { public static OpenAIContext Default { get; } protected override bool TryGetTypeBuilderCore(Type type, out ModelReaderWriterTypeBuilder builder); @@ -3511,7 +3512,11 @@ public class ImageClient { public virtual Task> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null); } public class ImageEditOptions : IJsonModel, IPersistableModel { + [Experimental("OPENAI001")] + public GeneratedImageBackground? Background { get; set; } public string EndUserId { get; set; } + [Experimental("OPENAI001")] + public GeneratedImageQuality? Quality { get; set; } public GeneratedImageFormat? ResponseFormat { get; set; } public GeneratedImageSize? Size { get; set; } [Experimental("OPENAI001")] diff --git a/api/OpenAI.netstandard2.0.cs b/api/OpenAI.netstandard2.0.cs index 085898631..e04c56420 100644 --- a/api/OpenAI.netstandard2.0.cs +++ b/api/OpenAI.netstandard2.0.cs @@ -3063,7 +3063,9 @@ public class ImageClient { public virtual Task> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null); } public class ImageEditOptions : IJsonModel, IPersistableModel { + public GeneratedImageBackground? Background { get; set; } public string EndUserId { get; set; } + public GeneratedImageQuality? Quality { get; set; } public GeneratedImageFormat? ResponseFormat { get; set; } public GeneratedImageSize? Size { get; set; } protected virtual ImageEditOptions JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options); diff --git a/src/Custom/Images/ImageEditOptions.cs b/src/Custom/Images/ImageEditOptions.cs index 77ae13b9f..65a1cc77e 100644 --- a/src/Custom/Images/ImageEditOptions.cs +++ b/src/Custom/Images/ImageEditOptions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; namespace OpenAI.Images; @@ -68,6 +69,16 @@ public partial class ImageEditOptions /// The number of images to generate. Must be between 1 and 10. internal long? N { get; set; } + // CUSTOM: Changed property type. + [Experimental("OPENAI001")] + [CodeGenMember("Background")] + public GeneratedImageBackground? Background { get; set; } + + // CUSTOM: Changed property type. + [Experimental("OPENAI001")] + [CodeGenMember("Quality")] + public GeneratedImageQuality? Quality { get; set; } + // CUSTOM: Changed property type. /// The size of the generated images. Must be one of `256x256`, `512x512`, or `1024x1024`. [CodeGenMember("Size")] diff --git a/src/Custom/OpenAIContext.cs b/src/Custom/OpenAIContext.cs new file mode 100644 index 000000000..311e3cb09 --- /dev/null +++ b/src/Custom/OpenAIContext.cs @@ -0,0 +1,8 @@ +using System.Diagnostics.CodeAnalysis; + +namespace OpenAI; + +[Experimental("OPENAI001")] +public partial class OpenAIContext +{ +} \ No newline at end of file diff --git a/src/Generated/Models/Images/ImageEditOptions.Serialization.cs b/src/Generated/Models/Images/ImageEditOptions.Serialization.cs index e28064111..99a46696b 100644 --- a/src/Generated/Models/Images/ImageEditOptions.Serialization.cs +++ b/src/Generated/Models/Images/ImageEditOptions.Serialization.cs @@ -134,13 +134,13 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element BinaryData image = default; string prompt = default; BinaryData mask = default; - InternalCreateImageEditRequestBackground? background = default; + GeneratedImageBackground? background = default; InternalCreateImageEditRequestModel? model = default; long? n = default; GeneratedImageSize? size = default; GeneratedImageFormat? responseFormat = default; string endUserId = default; - InternalCreateImageEditRequestQuality? quality = default; + GeneratedImageQuality? quality = default; IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary(); foreach (var prop in element.EnumerateObject()) { @@ -170,7 +170,7 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element background = null; continue; } - background = new InternalCreateImageEditRequestBackground(prop.Value.GetString()); + background = new GeneratedImageBackground(prop.Value.GetString()); continue; } if (prop.NameEquals("model"u8)) @@ -225,7 +225,7 @@ internal static ImageEditOptions DeserializeImageEditOptions(JsonElement element quality = null; continue; } - quality = new InternalCreateImageEditRequestQuality(prop.Value.GetString()); + quality = new GeneratedImageQuality(prop.Value.GetString()); continue; } // Plugin customization: remove options.Format != "W" check diff --git a/src/Generated/Models/Images/ImageEditOptions.cs b/src/Generated/Models/Images/ImageEditOptions.cs index ecc84184d..9e0dae515 100644 --- a/src/Generated/Models/Images/ImageEditOptions.cs +++ b/src/Generated/Models/Images/ImageEditOptions.cs @@ -11,7 +11,7 @@ public partial class ImageEditOptions { private protected IDictionary _additionalBinaryDataProperties; - internal ImageEditOptions(BinaryData image, string prompt, BinaryData mask, InternalCreateImageEditRequestBackground? background, InternalCreateImageEditRequestModel? model, long? n, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, InternalCreateImageEditRequestQuality? quality, IDictionary additionalBinaryDataProperties) + internal ImageEditOptions(BinaryData image, string prompt, BinaryData mask, GeneratedImageBackground? background, InternalCreateImageEditRequestModel? model, long? n, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, GeneratedImageQuality? quality, IDictionary additionalBinaryDataProperties) { Image = image; Prompt = prompt; @@ -26,10 +26,6 @@ internal ImageEditOptions(BinaryData image, string prompt, BinaryData mask, Inte _additionalBinaryDataProperties = additionalBinaryDataProperties; } - internal InternalCreateImageEditRequestBackground? Background { get; set; } - - internal InternalCreateImageEditRequestQuality? Quality { get; set; } - internal IDictionary SerializedAdditionalRawData { get => _additionalBinaryDataProperties; diff --git a/src/Generated/OpenAIModelFactory.cs b/src/Generated/OpenAIModelFactory.cs index bc1a8918a..bc73c3220 100644 --- a/src/Generated/OpenAIModelFactory.cs +++ b/src/Generated/OpenAIModelFactory.cs @@ -737,6 +737,22 @@ public static ImageInputTokenUsageDetails ImageInputTokenUsageDetails(int textTo return new ImageInputTokenUsageDetails(textTokenCount, imageTokenCount, additionalBinaryDataProperties: null); } + public static ImageEditOptions ImageEditOptions(BinaryData image = default, string prompt = default, BinaryData mask = default, GeneratedImageBackground? background = default, InternalCreateImageEditRequestModel? model = default, long? n = default, GeneratedImageSize? size = default, GeneratedImageFormat? responseFormat = default, string endUserId = default, GeneratedImageQuality? quality = default) + { + return new ImageEditOptions( + image, + prompt, + mask, + background, + model, + n, + size, + responseFormat, + endUserId, + quality, + additionalBinaryDataProperties: null); + } + public static ImageVariationOptions ImageVariationOptions(BinaryData image = default, InternalCreateImageVariationRequestModel? model = default, long? n = default, GeneratedImageFormat? responseFormat = default, GeneratedImageSize? size = default, string endUserId = default) { return new ImageVariationOptions( diff --git a/tests/Images/ImageEditsTests.cs b/tests/Images/ImageEditsTests.cs index 4d20c8a17..5c3da371c 100644 --- a/tests/Images/ImageEditsTests.cs +++ b/tests/Images/ImageEditsTests.cs @@ -58,6 +58,48 @@ public async Task GenerateImageEditWorks(ImageSourceKind imageSourceKind) ValidateGeneratedImage(image.ImageUri, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); } + [Test] + [TestCaseSource(nameof(s_imageSourceKindSource))] + public async Task GptImage1Works(ImageSourceKind imageSourceKind) + { + ImageClient client = GetTestClient(TestScenario.Images, "gpt-image-1"); + + string maskFilename = "images_empty_room_with_mask.png"; + string maskImagePath = Path.Combine("Assets", maskFilename); + GeneratedImage image = null; + + ImageEditOptions options = new() + { + Background = GeneratedImageBackground.Opaque, + Quality = GeneratedImageQuality.Low, + Size = GeneratedImageSize.W1024xH1024 + }; + + if (imageSourceKind == ImageSourceKind.UsingStream) + { + using FileStream mask = File.OpenRead(maskImagePath); + + image = IsAsync + ? await client.GenerateImageEditAsync(mask, maskFilename, CatPrompt, options) + : client.GenerateImageEdit(mask, maskFilename, CatPrompt, options); + } + else if (imageSourceKind == ImageSourceKind.UsingFilePath) + { + image = IsAsync + ? await client.GenerateImageEditAsync(maskImagePath, CatPrompt, options) + : client.GenerateImageEdit(maskImagePath, CatPrompt, options); + } + else + { + Assert.Fail("Invalid source kind."); + } + + Assert.That(image.ImageUri, Is.Null); + Assert.That(image.ImageBytes, Is.Not.Null); + + ValidateGeneratedImage(image.ImageBytes, ["cat", "owl", "animal"], "Note that it likely depicts some sort of animal."); + } + [Test] [TestCaseSource(nameof(s_imageSourceKindSource))] public async Task GenerateImageEditWithBytesResponseWorks(ImageSourceKind imageSourceKind)