diff --git a/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs b/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs index 17fad1581f..a10cc11d79 100644 --- a/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs +++ b/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; +using System.Diagnostics; using System.IO; using System.Threading.Tasks; using AgentConformance.IntegrationTests.Support; @@ -108,6 +109,9 @@ You are a helpful agent that can help fetch data from files you know about. ); var vectorStoreMetadata = await this._persistentAgentsClient.VectorStores.CreateVectorStoreAsync([uploadedAgentFile.Id], name: "WordCodeLookup_VectorStore"); + // Wait for vector store indexing to complete before using it + await this.WaitForVectorStoreReadyAsync(this._persistentAgentsClient, vectorStoreMetadata.Value.Id); + // Act. var agent = createMechanism switch { @@ -292,4 +296,42 @@ public async Task CreateAgent_CreatesAgentWithAIFunctionToolsAsync(string create await this._persistentAgentsClient.Administration.DeleteAgentAsync(agent.Id); } } + + /// + /// Waits for a vector store to complete indexing by polling its status. + /// + /// The persistent agents client. + /// The ID of the vector store. + /// Maximum time to wait in seconds (default: 30). + /// A task that completes when the vector store is ready or throws on timeout/failure. + private async Task WaitForVectorStoreReadyAsync( + PersistentAgentsClient client, + string vectorStoreId, + int maxWaitSeconds = 30) + { + Stopwatch sw = Stopwatch.StartNew(); + while (sw.Elapsed.TotalSeconds < maxWaitSeconds) + { + PersistentAgentsVectorStore vectorStore = await client.VectorStores.GetVectorStoreAsync(vectorStoreId); + + if (vectorStore.Status == VectorStoreStatus.Completed) + { + if (vectorStore.FileCounts.Failed > 0) + { + throw new InvalidOperationException("Vector store indexing failed for some files"); + } + + return; + } + + if (vectorStore.Status == VectorStoreStatus.Expired) + { + throw new InvalidOperationException("Vector store has expired"); + } + + await Task.Delay(1000); + } + + throw new TimeoutException($"Vector store did not complete indexing within {maxWaitSeconds}s"); + } } diff --git a/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs b/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs index d187d85b78..f1373bd98b 100644 --- a/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs +++ b/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; +using System.Diagnostics; using System.IO; using System.Threading.Tasks; using AgentConformance.IntegrationTests.Support; @@ -173,6 +174,9 @@ You are a helpful agent that can help fetch data from files you know about. }); string vectorStoreId = vectorStoreCreate.Value.Id; + // Wait for vector store indexing to complete before using it + await WaitForVectorStoreReadyAsync(vectorStoreClient, vectorStoreId); + var fileSearchTool = new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreId)] }; var agent = createMechanism switch @@ -219,4 +223,43 @@ You are a helpful agent that can help fetch data from files you know about. File.Delete(searchFilePath); } } + + /// + /// Waits for a vector store to complete indexing by polling its status. + /// + /// The vector store client. + /// The ID of the vector store. + /// Maximum time to wait in seconds (default: 30). + /// A task that completes when the vector store is ready or throws on timeout/failure. + private static async Task WaitForVectorStoreReadyAsync( + VectorStoreClient client, + string vectorStoreId, + int maxWaitSeconds = 30) + { + Stopwatch sw = Stopwatch.StartNew(); + while (sw.Elapsed.TotalSeconds < maxWaitSeconds) + { + VectorStore vectorStore = await client.GetVectorStoreAsync(vectorStoreId); + VectorStoreStatus status = vectorStore.Status; + + if (status == VectorStoreStatus.Completed) + { + if (vectorStore.FileCounts.Failed > 0) + { + throw new InvalidOperationException("Vector store indexing failed for some files"); + } + + return; + } + + if (status == VectorStoreStatus.Expired) + { + throw new InvalidOperationException("Vector store has expired"); + } + + await Task.Delay(1000); + } + + throw new TimeoutException($"Vector store did not complete indexing within {maxWaitSeconds}s"); + } }