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
5 changes: 5 additions & 0 deletions api/OpenAI.net8.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -3511,7 +3512,11 @@ public class ImageClient {
public virtual Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null);
}
public class ImageEditOptions : IJsonModel<ImageEditOptions>, IPersistableModel<ImageEditOptions> {
[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")]
Expand Down
2 changes: 2 additions & 0 deletions api/OpenAI.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3063,7 +3063,9 @@ public class ImageClient {
public virtual Task<ClientResult<GeneratedImageCollection>> GenerateImageVariationsAsync(string imageFilePath, int imageCount, ImageVariationOptions options = null);
}
public class ImageEditOptions : IJsonModel<ImageEditOptions>, IPersistableModel<ImageEditOptions> {
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);
Expand Down
11 changes: 11 additions & 0 deletions src/Custom/Images/ImageEditOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;

namespace OpenAI.Images;
Expand Down Expand Up @@ -68,6 +69,16 @@ public partial class ImageEditOptions
/// <summary> The number of images to generate. Must be between 1 and 10. </summary>
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.
/// <summary> The size of the generated images. Must be one of `256x256`, `512x512`, or `1024x1024`. </summary>
[CodeGenMember("Size")]
Expand Down
8 changes: 8 additions & 0 deletions src/Custom/OpenAIContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Diagnostics.CodeAnalysis;

namespace OpenAI;

[Experimental("OPENAI001")]
public partial class OpenAIContext
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
foreach (var prop in element.EnumerateObject())
{
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down
6 changes: 1 addition & 5 deletions src/Generated/Models/Images/ImageEditOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class ImageEditOptions
{
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;

internal ImageEditOptions(BinaryData image, string prompt, BinaryData mask, InternalCreateImageEditRequestBackground? background, InternalCreateImageEditRequestModel? model, long? n, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, InternalCreateImageEditRequestQuality? quality, IDictionary<string, BinaryData> additionalBinaryDataProperties)
internal ImageEditOptions(BinaryData image, string prompt, BinaryData mask, GeneratedImageBackground? background, InternalCreateImageEditRequestModel? model, long? n, GeneratedImageSize? size, GeneratedImageFormat? responseFormat, string endUserId, GeneratedImageQuality? quality, IDictionary<string, BinaryData> additionalBinaryDataProperties)
{
Image = image;
Prompt = prompt;
Expand All @@ -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<string, BinaryData> SerializedAdditionalRawData
{
get => _additionalBinaryDataProperties;
Expand Down
16 changes: 16 additions & 0 deletions src/Generated/OpenAIModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
42 changes: 42 additions & 0 deletions tests/Images/ImageEditsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ImageClient>(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)
Expand Down