diff --git a/.github/workflows/live-test.yml b/.github/workflows/live-test.yml index 8f285de35..88e7a23bb 100644 --- a/.github/workflows/live-test.yml +++ b/.github/workflows/live-test.yml @@ -32,7 +32,7 @@ jobs: - name: Run live tests run: dotnet test ./tests/OpenAI.Tests.csproj --configuration Release - --filter="TestCategory!=Smoke&TestCategory!=Assistants&TestCategory!=StoredChat&TestCategory!=Images&TestCategory!=Uploads&TestCategory!=Moderations&TestCategory!=FineTuning&TestCategory!=Conversation&TestCategory!=MCP&TestCategory!=Manual" + --filter="TestCategory!=Smoke&TestCategory!=Assistants&TestCategory!=StoredChat&TestCategory!=Images&TestCategory!=Uploads&TestCategory!=Moderations&TestCategory!=FineTuning&TestCategory!=Containers&TestCategory!=Conversation&TestCategory!=MCP&TestCategory!=Manual" --logger "trx;LogFilePrefix=live" --results-directory ${{github.workspace}}/artifacts/test-results ${{ env.version_suffix_args}} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 27f997f6c..8abf3de71 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: - name: Run Live Tests run: dotnet test ./tests/OpenAI.Tests.csproj --configuration Release - --filter="TestCategory!=Smoke&TestCategory!=Assistants&TestCategory!=StoredChat&TestCategory!=Images&TestCategory!=Uploads&TestCategory!=Moderations&TestCategory!=FineTuning&TestCategory!=Conversation&TestCategory!=MCP&TestCategory!=Manual" + --filter="TestCategory!=Smoke&TestCategory!=Assistants&TestCategory!=StoredChat&TestCategory!=Images&TestCategory!=Uploads&TestCategory!=Moderations&TestCategory!=FineTuning&TestCategory!=Containers&TestCategory!=Conversation&TestCategory!=MCP&TestCategory!=Manual" --logger "trx;LogFilePrefix=live" --results-directory ${{ github.workspace }}/artifacts/test-results ${{ env.version_suffix_args }} diff --git a/tests/Responses/ResponsesTests.cs b/tests/Responses/ResponsesTests.cs index cfd028874..50c88b77d 100644 --- a/tests/Responses/ResponsesTests.cs +++ b/tests/Responses/ResponsesTests.cs @@ -73,58 +73,6 @@ private void Validate(T input) where T : class } } - [Test] - public async Task FileSearch() - { - OpenAIFileClient fileClient = GetTestClient(TestScenario.Files); - OpenAIFile testFile = await fileClient.UploadFileAsync( - BinaryData.FromString(""" - Travis's favorite food is pizza. - """), - "test_favorite_foods.txt", - FileUploadPurpose.UserData); - Validate(testFile); - - VectorStoreClient vscClient = GetTestClient(TestScenario.VectorStores); - VectorStore vectorStore = await vscClient.CreateVectorStoreAsync( - new VectorStoreCreationOptions() - { - FileIds = { testFile.Id }, - }); - Validate(vectorStore); - - OpenAIResponseClient client = GetTestClient(); - - OpenAIResponse response = await client.CreateResponseAsync( - "Using the file search tool, what's Travis's favorite food?", - new ResponseCreationOptions() - { - Tools = - { - ResponseTool.CreateFileSearchTool(vectorStoreIds: [vectorStore.Id]), - } - }); - Assert.That(response.OutputItems?.Count, Is.EqualTo(2)); - FileSearchCallResponseItem fileSearchCall = response.OutputItems[0] as FileSearchCallResponseItem; - Assert.That(fileSearchCall, Is.Not.Null); - Assert.That(fileSearchCall?.Status, Is.EqualTo(FileSearchCallStatus.Completed)); - Assert.That(fileSearchCall?.Queries, Has.Count.GreaterThan(0)); - MessageResponseItem message = response.OutputItems[1] as MessageResponseItem; - Assert.That(message, Is.Not.Null); - ResponseContentPart messageContentPart = message.Content?.FirstOrDefault(); - Assert.That(messageContentPart, Is.Not.Null); - Assert.That(messageContentPart.Text, Does.Contain("pizza")); - Assert.That(messageContentPart.OutputTextAnnotations, Is.Not.Null.And.Not.Empty); - FileCitationMessageAnnotation annotation = messageContentPart.OutputTextAnnotations[0] as FileCitationMessageAnnotation; - Assert.That(annotation.FileId, Is.EqualTo(testFile.Id)); - Assert.That(annotation.Index, Is.GreaterThan(0)); - - await foreach (ResponseItem inputItem in client.GetResponseInputItemsAsync(response.Id)) - { - Console.WriteLine(ModelReaderWriter.Write(inputItem).ToString()); - } - } - [Test] public async Task ComputerToolWithScreenshotRoundTrip() { diff --git a/tests/Responses/ResponsesToolTests.cs b/tests/Responses/ResponsesToolTests.cs index 39cbb959f..e4a6bbcad 100644 --- a/tests/Responses/ResponsesToolTests.cs +++ b/tests/Responses/ResponsesToolTests.cs @@ -1,8 +1,11 @@ using NUnit.Framework; +using OpenAI.Files; using OpenAI.Responses; using OpenAI.Tests.Utility; +using OpenAI.VectorStores; using System; using System.ClientModel; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Linq; using System.Text; @@ -335,5 +338,72 @@ public async Task MCPToolWithDisallowedTools() Assert.That(response.OutputItems.OfType().ToList(), Has.Count.EqualTo(0)); } + [Test] + public async Task FileSearch() + { + OpenAIFileClient fileClient = GetTestClient(TestScenario.Files); + OpenAIFile testFile = await fileClient.UploadFileAsync( + BinaryData.FromString(""" + Travis's favorite food is pizza. + """), + "test_favorite_foods.txt", + FileUploadPurpose.UserData); + Validate(testFile); + + VectorStoreClient vscClient = GetTestClient(TestScenario.VectorStores); + VectorStore vectorStore = await vscClient.CreateVectorStoreAsync( + new VectorStoreCreationOptions() + { + FileIds = { testFile.Id }, + }); + Validate(vectorStore); + + OpenAIResponseClient client = GetTestClient(); + + OpenAIResponse response = await client.CreateResponseAsync( + "Using the file search tool, what's Travis's favorite food?", + new ResponseCreationOptions() + { + Tools = + { + ResponseTool.CreateFileSearchTool(vectorStoreIds: [vectorStore.Id]), + } + }); + Assert.That(response.OutputItems?.Count, Is.EqualTo(2)); + FileSearchCallResponseItem fileSearchCall = response.OutputItems[0] as FileSearchCallResponseItem; + Assert.That(fileSearchCall, Is.Not.Null); + Assert.That(fileSearchCall?.Status, Is.EqualTo(FileSearchCallStatus.Completed)); + Assert.That(fileSearchCall?.Queries, Has.Count.GreaterThan(0)); + MessageResponseItem message = response.OutputItems[1] as MessageResponseItem; + Assert.That(message, Is.Not.Null); + ResponseContentPart messageContentPart = message.Content?.FirstOrDefault(); + Assert.That(messageContentPart, Is.Not.Null); + Assert.That(messageContentPart.Text, Does.Contain("pizza")); + Assert.That(messageContentPart.OutputTextAnnotations, Is.Not.Null.And.Not.Empty); + FileCitationMessageAnnotation annotation = messageContentPart.OutputTextAnnotations[0] as FileCitationMessageAnnotation; + Assert.That(annotation.FileId, Is.EqualTo(testFile.Id)); + Assert.That(annotation.Index, Is.GreaterThan(0)); + + await foreach (ResponseItem inputItem in client.GetResponseInputItemsAsync(response.Id)) + { + Console.WriteLine(ModelReaderWriter.Write(inputItem).ToString()); + } + } + + private List FileIdsToDelete = []; + private List VectorStoreIdsToDelete = []; + + private void Validate(T input) where T : class + { + if (input is OpenAIFile file) + { + FileIdsToDelete.Add(file.Id); + } + if (input is VectorStore vectorStore) + { + VectorStoreIdsToDelete.Add(vectorStore.Id); + } + } + private static OpenAIResponseClient GetTestClient(string overrideModel = null) => GetTestClient(TestScenario.Responses, overrideModel); } \ No newline at end of file