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
32 changes: 17 additions & 15 deletions tests/Assistants/Assistants.VectorStoresTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using static OpenAI.Tests.TestHelpers;

Expand Down Expand Up @@ -177,10 +176,9 @@ public async Task CanAssociateFiles()
Assert.That(removalResult.Removed);
_vectorStoreFilesToRemove.RemoveAt(0);

// Errata: removals aren't immediately reflected when requesting the list
if (Mode != RecordedTestMode.Playback)
{
Thread.Sleep(2000);
await Task.Delay(TimeSpan.FromSeconds(10));
}

int count = 0;
Expand Down Expand Up @@ -220,10 +218,9 @@ public async Task Pagination_CanRehydrateVectorStoreFileCollection()
FileFromStoreRemovalResult removalResult = await client.RemoveFileFromVectorStoreAsync(vectorStore.Id, files[0].Id);
Assert.That(removalResult.FileId, Is.EqualTo(files[0].Id));

// Errata: removals aren't immediately reflected when requesting the list
if (Mode != RecordedTestMode.Playback)
{
Thread.Sleep(2000);
await Task.Delay(TimeSpan.FromSeconds(10));
}

// We added 6 files and will get pages with 2 items, so expect three pages in the collection.
Expand Down Expand Up @@ -293,7 +290,7 @@ public async Task CanPaginateGetVectorStoreFilesInBatch()

if (Mode != RecordedTestMode.Playback)
{
await Task.Delay(TimeSpan.FromSeconds(1));
await Task.Delay(TimeSpan.FromSeconds(10));
}

// Test basic pagination with PageSizeLimit
Expand Down Expand Up @@ -356,24 +353,29 @@ public async Task CanTestGetVectorStoreFilesInBatchCollectionOptions()
VectorStoreClient client = GetTestClient();
VectorStore vectorStore = await client.CreateVectorStoreAsync();
Validate(vectorStore);
int pageSizeLimit = 2;
int fileCount = pageSizeLimit + 1;

// Create files for testing
IReadOnlyList<OpenAIFile> testFiles = await GetNewTestFiles(8);
IReadOnlyList<OpenAIFile> testFiles = await GetNewTestFiles(fileCount);

VectorStoreFileBatch fileBatch = await client.AddFileBatchToVectorStoreAsync(vectorStore.Id, testFiles?.Select(file => file.Id));
Validate(fileBatch);
await Task.Delay(TimeSpan.FromSeconds(1));

if (Mode != RecordedTestMode.Playback)
{
await Task.Delay(TimeSpan.FromSeconds(10));
}

// Test Order property - Ascending vs Descending
var ascendingOptions = new VectorStoreFileCollectionOptions
{
Order = VectorStoreFileCollectionOrder.Ascending,
PageSizeLimit = 5
PageSizeLimit = pageSizeLimit
};
var descendingOptions = new VectorStoreFileCollectionOptions
{
Order = VectorStoreFileCollectionOrder.Descending,
PageSizeLimit = 5
PageSizeLimit = pageSizeLimit
};

List<string> ascendingIds = [];
Expand All @@ -389,9 +391,8 @@ public async Task CanTestGetVectorStoreFilesInBatchCollectionOptions()
descendingIds.Add(vectorStoreFile.FileId);
}

// The lists should be reverse of each other
Assert.That(ascendingIds.Count, Is.EqualTo(fileCount));
Assert.That(ascendingIds.Count, Is.EqualTo(descendingIds.Count));
Assert.That(ascendingIds.SequenceEqual(descendingIds.AsEnumerable().Reverse()), Is.True);

// Test Filter property - only get completed files (which should be all of them after batch completion)
var filterOptions = new VectorStoreFileCollectionOptions
Expand All @@ -406,7 +407,7 @@ public async Task CanTestGetVectorStoreFilesInBatchCollectionOptions()
Assert.That(vectorStoreFile.Status, Is.EqualTo(VectorStoreFileStatus.Completed));
}

Assert.That(completedCount, Is.EqualTo(8)); // Should match the number of files we uploaded
Assert.That(completedCount, Is.EqualTo(fileCount)); // Should match the number of files we uploaded

// Test AfterId property - get vector store files after a specific ID
var firstVectorStoreFile = ascendingIds.FirstOrDefault();
Expand Down Expand Up @@ -464,9 +465,10 @@ public async Task CanRehydrateGetVectorStoreFilesInBatchPagination()

VectorStoreFileBatch fileBatch = await client.AddFileBatchToVectorStoreAsync(vectorStore.Id, testFiles?.Select(file => file.Id));
Validate(fileBatch);

if (Mode != RecordedTestMode.Playback)
{
await Task.Delay(TimeSpan.FromSeconds(1));
await Task.Delay(TimeSpan.FromSeconds(10));
}

// We added 6 files and will get pages with 2 items, so expect three pages in the collection.
Expand Down
6 changes: 3 additions & 3 deletions tests/Moderations/ModerationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task ClassifySingleInput()
Assert.That(moderation, Is.Not.Null);
Assert.That(moderation.Flagged, Is.True);
Assert.That(moderation.Violence.Flagged, Is.True);
Assert.That(moderation.Violence.Score, Is.GreaterThan(0.5));
Assert.That(moderation.Violence.Score, Is.GreaterThan(0.2));
}

[RecordedTest]
Expand All @@ -43,7 +43,7 @@ public async Task ClassifyMultipleInputs()
ModerationResultCollection moderations = await client.ClassifyTextAsync(inputs);
Assert.That(moderations, Is.Not.Null);
Assert.That(moderations.Count, Is.EqualTo(2));
Assert.That(moderations.Model, Does.StartWith("text-moderation"));
Assert.That(moderations.Model, Does.StartWith("omni"));
Assert.That(moderations.Id, Is.Not.Null.Or.Empty);

Assert.That(moderations[0], Is.Not.Null);
Expand All @@ -52,6 +52,6 @@ public async Task ClassifyMultipleInputs()
Assert.That(moderations[1], Is.Not.Null);
Assert.That(moderations[1].Flagged, Is.True);
Assert.That(moderations[1].Violence.Flagged, Is.True);
Assert.That(moderations[1].Violence.Score, Is.GreaterThan(0.5));
Assert.That(moderations[1].Violence.Score, Is.GreaterThan(0.2));
}
}
246 changes: 0 additions & 246 deletions tests/Responses/ResponsesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,252 +228,6 @@ in client.CreateResponseStreamingAsync(message, responseOptions))
Assert.That(searchItemId, Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task ResponseWithImageGenTool()
{
OpenAIResponseClient client = GetTestClient();

ResponseCreationOptions options = new()
{
Tools =
{
ResponseTool.CreateImageGenerationTool(
model: "gpt-image-1",
quality: ImageGenerationToolQuality.High,
size: ImageGenerationToolSize.W1024xH1024,
outputFileFormat: ImageGenerationToolOutputFileFormat.Png,
moderationLevel: ImageGenerationToolModerationLevel.Auto,
background: ImageGenerationToolBackground.Transparent,
inputFidelity: ImageGenerationToolInputFidelity.High)
}
};

OpenAIResponse response = await client.CreateResponseAsync(
"Generate an image of gray tabby cat hugging an otter with an orange scarf",
options);

Assert.That(response.OutputItems, Has.Count.EqualTo(2));
Assert.That(response.OutputItems[0], Is.InstanceOf<ImageGenerationCallResponseItem>());
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());

MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
Assert.That(message.Content, Has.Count.GreaterThan(0));
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));

Assert.That(response.Tools.FirstOrDefault(), Is.TypeOf<ImageGenerationTool>());

ImageGenerationCallResponseItem imageGenResponse = (ImageGenerationCallResponseItem)response.OutputItems[0];
Assert.That(imageGenResponse.Status, Is.EqualTo(ImageGenerationCallStatus.Completed));
Assert.That(imageGenResponse.ImageResultBytes.ToArray(), Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task ImageGenToolStreaming()
{
OpenAIResponseClient client = GetTestClient();

const string message = "Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape";

ResponseCreationOptions responseOptions = new()
{
Tools =
{
ResponseTool.CreateImageGenerationTool(
model: "gpt-image-1",
quality: ImageGenerationToolQuality.High,
size: ImageGenerationToolSize.W1024xH1024,
outputFileFormat: ImageGenerationToolOutputFileFormat.Png,
moderationLevel: ImageGenerationToolModerationLevel.Auto,
background: ImageGenerationToolBackground.Transparent)
}
};

string imageGenItemId = null;
int partialCount = 0;
int inProgressCount = 0;
int generateCount = 0;
bool gotCompletedImageGenItem = false;
bool gotCompletedResponseItem = false;

await foreach (StreamingResponseUpdate update
in client.CreateResponseStreamingAsync(message, responseOptions))
{
if (update is StreamingResponseImageGenerationCallPartialImageUpdate imageGenCallInPartialUpdate)
{
Assert.That(imageGenCallInPartialUpdate.ItemId, Is.Not.Null.And.Not.Empty);
imageGenItemId ??= imageGenCallInPartialUpdate.ItemId;
Assert.That(imageGenItemId, Is.EqualTo(imageGenCallInPartialUpdate.ItemId));
Assert.That(imageGenCallInPartialUpdate.OutputIndex, Is.EqualTo(0));
partialCount++;
}
else if (update is StreamingResponseImageGenerationCallInProgressUpdate imageGenCallInProgressUpdate)
{
Assert.That(imageGenCallInProgressUpdate.ItemId, Is.Not.Null.And.Not.Empty);
imageGenItemId ??= imageGenCallInProgressUpdate.ItemId;
Assert.That(imageGenItemId, Is.EqualTo(imageGenCallInProgressUpdate.ItemId));
Assert.That(imageGenCallInProgressUpdate.OutputIndex, Is.EqualTo(0));
inProgressCount++;
}
else if (update is StreamingResponseImageGenerationCallGeneratingUpdate imageGenCallGeneratingUpdate)
{
Assert.That(imageGenCallGeneratingUpdate.ItemId, Is.Not.Null.And.Not.Empty);
imageGenItemId ??= imageGenCallGeneratingUpdate.ItemId;
Assert.That(imageGenItemId, Is.EqualTo(imageGenCallGeneratingUpdate.ItemId));
Assert.That(imageGenCallGeneratingUpdate.OutputIndex, Is.EqualTo(0));
generateCount++;
}
else if (update is StreamingResponseImageGenerationCallCompletedUpdate outputItemCompleteUpdate)
{
Assert.That(outputItemCompleteUpdate.ItemId, Is.Not.Null.And.Not.Empty);
imageGenItemId ??= outputItemCompleteUpdate.ItemId;
Assert.That(imageGenItemId, Is.EqualTo(outputItemCompleteUpdate.ItemId));
Assert.That(outputItemCompleteUpdate.OutputIndex, Is.EqualTo(0));
gotCompletedImageGenItem = true;
}
else if (update is StreamingResponseOutputItemDoneUpdate outputItemDoneUpdate)
{
if (outputItemDoneUpdate.Item is ImageGenerationCallResponseItem imageGenCallItem)
{
Assert.That(imageGenCallItem.Id, Is.Not.Null.And.Not.Empty);
imageGenItemId ??= imageGenCallItem.Id;
Assert.That(imageGenItemId, Is.EqualTo(outputItemDoneUpdate.Item.Id));
Assert.That(outputItemDoneUpdate.OutputIndex, Is.EqualTo(0));
gotCompletedResponseItem = true;
}
}
}

Assert.That(gotCompletedResponseItem || gotCompletedImageGenItem, Is.True);
Assert.That(partialCount, Is.EqualTo(1));
Assert.That(inProgressCount, Is.EqualTo(1));
Assert.That(generateCount, Is.EqualTo(1));
Assert.That(imageGenItemId, Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task ImageGenToolInputMaskWithImageBytes()
{
OpenAIResponseClient client = GetTestClient();

string imageFilename = "images_dog_and_cat.png";
string imagePath = Path.Combine("Assets", imageFilename);
ResponseCreationOptions options = new()
{
Tools =
{
ResponseTool.CreateImageGenerationTool(
model: "gpt-image-1",
outputFileFormat: ImageGenerationToolOutputFileFormat.Png,
inputImageMask: new(BinaryData.FromBytes(File.ReadAllBytes(imagePath)), "image/png"))
}
};

OpenAIResponse response = await client.CreateResponseAsync(
"Generate an image of gray tabby cat hugging an otter with an orange scarf",
options);

Assert.That(response.OutputItems, Has.Count.EqualTo(2));
Assert.That(response.OutputItems[0], Is.InstanceOf<ImageGenerationCallResponseItem>());
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());

MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
Assert.That(message.Content, Has.Count.GreaterThan(0));
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));

Assert.That(response.Tools.FirstOrDefault(), Is.TypeOf<ImageGenerationTool>());

ImageGenerationCallResponseItem imageGenResponse = (ImageGenerationCallResponseItem)response.OutputItems[0];
Assert.That(imageGenResponse.Status, Is.EqualTo(ImageGenerationCallStatus.Completed));
Assert.That(imageGenResponse.ImageResultBytes.ToArray(), Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task ImageGenToolInputMaskWithImageUri()
{
OpenAIResponseClient client = GetTestClient();

ResponseCreationOptions options = new()
{
Tools =
{
ResponseTool.CreateImageGenerationTool(
model: "gpt-image-1",
outputFileFormat: ImageGenerationToolOutputFileFormat.Png,
inputImageMask: new(imageUri: new Uri("https://upload.wikimedia.org/wikipedia/commons/c/c3/Openai.png")))
}
};

OpenAIResponse response = await client.CreateResponseAsync(
"Generate an image of gray tabby cat hugging an otter with an orange scarf",
options);

Assert.That(response.OutputItems, Has.Count.EqualTo(2));
Assert.That(response.OutputItems[0], Is.InstanceOf<ImageGenerationCallResponseItem>());
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());

MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
Assert.That(message.Content, Has.Count.GreaterThan(0));
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));

Assert.That(response.Tools.FirstOrDefault(), Is.TypeOf<ImageGenerationTool>());

ImageGenerationCallResponseItem imageGenResponse = (ImageGenerationCallResponseItem)response.OutputItems[0];
Assert.That(imageGenResponse.Status, Is.EqualTo(ImageGenerationCallStatus.Completed));
Assert.That(imageGenResponse.ImageResultBytes.ToArray(), Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task ImageGenToolInputMaskWithFileId()
{
OpenAIResponseClient client = GetTestClient();

OpenAIFileClient fileClient = GetProxiedOpenAIClient<OpenAIFileClient>(TestScenario.Files);

string imageFilename = "images_dog_and_cat.png";
string imagePath = Path.Combine("Assets", imageFilename);
using Stream image = File.OpenRead(imagePath);
BinaryData imageData = BinaryData.FromStream(image);

OpenAIFile file;
using (Recording.DisableRequestBodyRecording()) // Temp pending https://github.com/Azure/azure-sdk-tools/issues/11901
{
file = await fileClient.UploadFileAsync(
imageData,
imageFilename,
FileUploadPurpose.UserData);
}
Validate(file);

ResponseCreationOptions options = new()
{
Tools =
{
ResponseTool.CreateImageGenerationTool(
model: "gpt-image-1",
outputFileFormat: ImageGenerationToolOutputFileFormat.Png,
inputImageMask: new(fileId: file.Id))
}
};

OpenAIResponse response = await client.CreateResponseAsync(
"Generate an image of gray tabby cat hugging an otter with an orange scarf",
options);

Assert.That(response.OutputItems, Has.Count.EqualTo(2));
Assert.That(response.OutputItems[0], Is.InstanceOf<ImageGenerationCallResponseItem>());
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());

MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
Assert.That(message.Content, Has.Count.GreaterThan(0));
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));

Assert.That(response.Tools.FirstOrDefault(), Is.TypeOf<ImageGenerationTool>());

ImageGenerationCallResponseItem imageGenResponse = (ImageGenerationCallResponseItem)response.OutputItems[0];
Assert.That(imageGenResponse.Status, Is.EqualTo(ImageGenerationCallStatus.Completed));
Assert.That(imageGenResponse.ImageResultBytes.ToArray(), Is.Not.Null.And.Not.Empty);
}

[RecordedTest]
public async Task StreamingResponses()
{
Expand Down
Loading