diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Program.cs b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Program.cs index 4ca52aa268..ba51c8c0e7 100644 --- a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Program.cs +++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Program.cs @@ -26,14 +26,14 @@ // agentVersion.Version = , // agentVersion.Name = -// You can retrieve an AIAgent for an already created server side agent version. +// You can use an AIAgent with an already created server side agent version. AIAgent existingJokerAgent = aiProjectClient.AsAIAgent(createdAgentVersion); // You can also create another AIAgent version by providing the same name with a different definition. -AIAgent newJokerAgent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: "You are extremely hilarious at telling jokes."); +AIAgent newJokerAgent = await aiProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: "You are extremely hilarious at telling jokes."); // You can also get the AIAgent latest version just providing its name. -AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName); +AIAgent jokerAgentLatest = await aiProjectClient.GetAIAgentAsync(name: JokerName); var latestAgentVersion = jokerAgentLatest.GetService()!; // The AIAgent version can be accessed via the GetService method. diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs index 9a7ee0736a..0a10930b75 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs @@ -28,14 +28,14 @@ // agentVersion.Version = , // agentVersion.Name = -// You can retrieve an AIAgent for an already created server side agent version. -AIAgent existingJokerAgent = aiProjectClient.GetAIAgent(createdAgentVersion); +// You can use an AIAgent with an already created server side agent version. +AIAgent existingJokerAgent = aiProjectClient.AsAIAgent(createdAgentVersion); // You can also create another AIAgent version by providing the same name with a different definition/instruction. -AIAgent newJokerAgent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: "You are extremely hilarious at telling jokes."); +AIAgent newJokerAgent = await aiProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: "You are extremely hilarious at telling jokes."); // You can also get the AIAgent latest version by just providing its name. -AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName); +AIAgent jokerAgentLatest = await aiProjectClient.GetAIAgentAsync(name: JokerName); AgentVersion latestAgentVersion = jokerAgentLatest.GetService()!; // The AIAgent version can be accessed via the GetService method. diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs index 8ebceaea26..6da363905e 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs @@ -23,8 +23,8 @@ // You can create a server side agent version with the Azure.AI.Agents SDK client below. AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options); -// You can retrieve an AIAgent for a already created server side agent version. -AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion); +// You can use an AIAgent with an already created server side agent version. +AIAgent jokerAgent = aiProjectClient.AsAIAgent(agentVersion); // Invoke the agent with streaming support. await foreach (AgentResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.")) diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs index 4ad3d86255..0446328449 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs @@ -22,8 +22,8 @@ // Create a server side agent version with the Azure.AI.Agents SDK client. AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options); -// Retrieve an AIAgent for the created server side agent version. -AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion); +// Use an AIAgent with an already created server side agent version. +AIAgent jokerAgent = aiProjectClient.AsAIAgent(agentVersion); // Invoke the agent with a multi-turn conversation, where the context is preserved in the thread object. AgentThread thread = await jokerAgent.GetNewThreadAsync(); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/Program.cs index aaeb90fafa..d252b82b1e 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/Program.cs @@ -44,7 +44,7 @@ Console.WriteLine($"Occupation: {response.Result.Occupation}"); // Create the ChatClientAgent with the specified name, instructions, and expected structured output the agent should produce. -ChatClientAgent agentWithPersonInfo = aiProjectClient.CreateAIAgent( +ChatClientAgent agentWithPersonInfo = await aiProjectClient.CreateAIAgentAsync( model: deploymentName, new ChatClientAgentOptions() { diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step07_Observability/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step07_Observability/Program.cs index 4ba3ee4d34..a247c1d0f7 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step07_Observability/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step07_Observability/Program.cs @@ -32,7 +32,7 @@ AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); // Define the agent you want to create. (Prompt Agent in this case) -AIAgent agent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions) +AIAgent agent = (await aiProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: JokerInstructions)) .AsBuilder() .UseOpenTelemetry(sourceName: sourceName) .Build(); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step08_DependencyInjection/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step08_DependencyInjection/Program.cs index d6d1dd8d9f..f94acf1e38 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step08_DependencyInjection/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step08_DependencyInjection/Program.cs @@ -2,6 +2,7 @@ // This sample shows how to use dependency injection to register an AIAgent and use it from a hosted service with a user input chat loop. +using System.ClientModel; using Azure.AI.Projects; using Azure.Identity; using Microsoft.Agents.AI; @@ -14,16 +15,27 @@ const string JokerInstructions = "You are good at telling jokes."; const string JokerName = "JokerAgent"; +AIProjectClient aIProjectClient = new(new Uri(endpoint), new AzureCliCredential()); + +// Create a new agent if one doesn't exist already. +ChatClientAgent agent; +try +{ + agent = await aIProjectClient.GetAIAgentAsync(name: JokerName); +} +catch (ClientResultException ex) when (ex.Status == 404) +{ + agent = await aIProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: JokerInstructions); +} + // Create a host builder that we will register services with and then run. HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); // Add the agents client to the service collection. -builder.Services.AddSingleton((sp) => new AIProjectClient(new Uri(endpoint), new AzureCliCredential())); +builder.Services.AddSingleton((sp) => aIProjectClient); // Add the AI agent to the service collection. -builder.Services.AddSingleton((sp) - => sp.GetRequiredService() - .CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions)); +builder.Services.AddSingleton((sp) => agent); // Add a sample service that will use the agent to respond to user input. builder.Services.AddHostedService(); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step09_UsingMcpClientAsTools/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step09_UsingMcpClientAsTools/Program.cs index a821c1194b..cfa4b39534 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step09_UsingMcpClientAsTools/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step09_UsingMcpClientAsTools/Program.cs @@ -30,7 +30,7 @@ Console.WriteLine($"Creating the agent '{agentName}' ..."); // Define the agent you want to create. (Prompt Agent in this case) -AIAgent agent = aiProjectClient.CreateAIAgent( +AIAgent agent = await aiProjectClient.CreateAIAgentAsync( name: agentName, model: deploymentName, instructions: "You answer questions related to GitHub repositories only.", diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs index fa841ca913..efaab99b8a 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs @@ -17,7 +17,7 @@ AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); // Define the agent you want to create. (Prompt Agent in this case) -AIAgent agent = aiProjectClient.CreateAIAgent(name: VisionName, model: deploymentName, instructions: VisionInstructions); +AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: VisionName, model: deploymentName, instructions: VisionInstructions); ChatMessage message = new(ChatRole.User, [ new TextContent("What do you see in this image?"), diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step11_AsFunctionTool/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step11_AsFunctionTool/Program.cs index e00b05d9cb..e29dff2953 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step11_AsFunctionTool/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step11_AsFunctionTool/Program.cs @@ -25,14 +25,14 @@ static string GetWeather([Description("The location to get the weather for.")] s // Create the weather agent with function tools. AITool weatherTool = AIFunctionFactory.Create(GetWeather); -AIAgent weatherAgent = aiProjectClient.CreateAIAgent( +AIAgent weatherAgent = await aiProjectClient.CreateAIAgentAsync( name: WeatherName, model: deploymentName, instructions: WeatherInstructions, tools: [weatherTool]); // Create the main agent, and provide the weather agent as a function tool. -AIAgent agent = aiProjectClient.CreateAIAgent( +AIAgent agent = await aiProjectClient.CreateAIAgentAsync( name: MainName, model: deploymentName, instructions: MainInstructions, diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs index 0c6b76612c..c1750e3387 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs @@ -34,7 +34,7 @@ static string GetDateTime() AITool getWeatherTool = AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather)); // Define the agent you want to create. (Prompt Agent in this case) -AIAgent originalAgent = aiProjectClient.CreateAIAgent( +AIAgent originalAgent = await aiProjectClient.CreateAIAgentAsync( name: AssistantName, model: deploymentName, instructions: AssistantInstructions, @@ -69,7 +69,7 @@ static string GetDateTime() // Special per-request middleware agent. Console.WriteLine("\n\n=== Example 4: Middleware with human in the loop function approval ==="); -AIAgent humanInTheLoopAgent = aiProjectClient.CreateAIAgent( +AIAgent humanInTheLoopAgent = await aiProjectClient.CreateAIAgentAsync( name: "HumanInTheLoopAgent", model: deploymentName, instructions: "You are an Human in the loop testing AI assistant that helps people find information.", diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step13_Plugins/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step13_Plugins/Program.cs index 0cd9674770..72ec26bdf7 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step13_Plugins/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step13_Plugins/Program.cs @@ -34,7 +34,7 @@ // Define the agent with plugin tools // Define the agent you want to create. (Prompt Agent in this case) -AIAgent agent = aiProjectClient.CreateAIAgent( +AIAgent agent = await aiProjectClient.CreateAIAgentAsync( name: AssistantName, model: deploymentName, instructions: AssistantInstructions, diff --git a/dotnet/samples/GettingStarted/Workflows/Declarative/HostedWorkflow/Program.cs b/dotnet/samples/GettingStarted/Workflows/Declarative/HostedWorkflow/Program.cs index ee5c229f3d..5d76a0e319 100644 --- a/dotnet/samples/GettingStarted/Workflows/Declarative/HostedWorkflow/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Declarative/HostedWorkflow/Program.cs @@ -45,7 +45,7 @@ public static async Task Main(string[] args) string workflowInput = GetWorkflowInput(args); - AIAgent agent = aiProjectClient.GetAIAgent(agentVersion); + AIAgent agent = aiProjectClient.AsAIAgent(agentVersion); AgentThread thread = await agent.GetNewThreadAsync(); diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/PersistentAgentsClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/PersistentAgentsClientExtensions.cs index 55c3c4f0bf..718f4fc700 100644 --- a/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/PersistentAgentsClientExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/PersistentAgentsClientExtensions.cs @@ -82,39 +82,6 @@ public static ChatClientAgent AsAIAgent( }, services: services); } - /// - /// Retrieves an existing server side agent, wrapped as a using the provided . - /// - /// The to create the with. - /// A for the persistent agent. - /// The ID of the server side agent to create a for. - /// Options that should apply to all runs of the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the persistent agent. - public static ChatClientAgent GetAIAgent( - this PersistentAgentsClient persistentAgentsClient, - string agentId, - ChatOptions? chatOptions = null, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (persistentAgentsClient is null) - { - throw new ArgumentNullException(nameof(persistentAgentsClient)); - } - - if (string.IsNullOrWhiteSpace(agentId)) - { - throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); - } - - var persistentAgentResponse = persistentAgentsClient.Administration.GetAgent(agentId, cancellationToken); - return persistentAgentsClient.AsAIAgent(persistentAgentResponse, chatOptions, clientFactory, services); - } - /// /// Retrieves an existing server side agent, wrapped as a using the provided . /// @@ -232,45 +199,6 @@ public static ChatClientAgent AsAIAgent( return new ChatClientAgent(chatClient, agentOptions, services: services); } - /// - /// Retrieves an existing server side agent, wrapped as a using the provided . - /// - /// The to create the with. - /// The ID of the server side agent to create a for. - /// Full set of options to configure the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the persistent agent. - /// Thrown when or is . - /// Thrown when is empty or whitespace. - public static ChatClientAgent GetAIAgent( - this PersistentAgentsClient persistentAgentsClient, - string agentId, - ChatClientAgentOptions options, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (persistentAgentsClient is null) - { - throw new ArgumentNullException(nameof(persistentAgentsClient)); - } - - if (string.IsNullOrWhiteSpace(agentId)) - { - throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); - } - - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } - - var persistentAgentResponse = persistentAgentsClient.Administration.GetAgent(agentId, cancellationToken); - return persistentAgentsClient.AsAIAgent(persistentAgentResponse, options, clientFactory, services); - } - /// /// Retrieves an existing server side agent, wrapped as a using the provided . /// @@ -366,122 +294,6 @@ public static async Task CreateAIAgentAsync( return await persistentAgentsClient.GetAIAgentAsync(createPersistentAgentResponse.Value.Id, clientFactory: clientFactory, services: services, cancellationToken: cancellationToken).ConfigureAwait(false); } - /// - /// Creates a new server side agent using the provided . - /// - /// The to create the agent with. - /// The model to be used by the agent. - /// The name of the agent. - /// The description of the agent. - /// The instructions for the agent. - /// The tools to be used by the agent. - /// The resources for the tools. - /// The temperature setting for the agent. - /// The top-p setting for the agent. - /// The response format for the agent. - /// The metadata for the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the newly created agent. - public static ChatClientAgent CreateAIAgent( - this PersistentAgentsClient persistentAgentsClient, - string model, - string? name = null, - string? description = null, - string? instructions = null, - IEnumerable? tools = null, - ToolResources? toolResources = null, - float? temperature = null, - float? topP = null, - BinaryData? responseFormat = null, - IReadOnlyDictionary? metadata = null, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (persistentAgentsClient is null) - { - throw new ArgumentNullException(nameof(persistentAgentsClient)); - } - - var createPersistentAgentResponse = persistentAgentsClient.Administration.CreateAgent( - model: model, - name: name, - description: description, - instructions: instructions, - tools: tools, - toolResources: toolResources, - temperature: temperature, - topP: topP, - responseFormat: responseFormat, - metadata: metadata, - cancellationToken: cancellationToken); - - // Get a local proxy for the agent to work with. - return persistentAgentsClient.GetAIAgent(createPersistentAgentResponse.Value.Id, clientFactory: clientFactory, services: services, cancellationToken: cancellationToken); - } - - /// - /// Creates a new server side agent using the provided . - /// - /// The to create the agent with. - /// The model to be used by the agent. - /// Full set of options to configure the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the newly created agent. - /// Thrown when or or is . - /// Thrown when is empty or whitespace. - public static ChatClientAgent CreateAIAgent( - this PersistentAgentsClient persistentAgentsClient, - string model, - ChatClientAgentOptions options, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (persistentAgentsClient is null) - { - throw new ArgumentNullException(nameof(persistentAgentsClient)); - } - - if (string.IsNullOrWhiteSpace(model)) - { - throw new ArgumentException($"{nameof(model)} should not be null or whitespace.", nameof(model)); - } - - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } - - var toolDefinitionsAndResources = ConvertAIToolsToToolDefinitions(options.ChatOptions?.Tools); - - var createPersistentAgentResponse = persistentAgentsClient.Administration.CreateAgent( - model: model, - name: options.Name, - description: options.Description, - instructions: options.ChatOptions?.Instructions, - tools: toolDefinitionsAndResources.ToolDefinitions, - toolResources: toolDefinitionsAndResources.ToolResources, - temperature: null, - topP: null, - responseFormat: null, - metadata: null, - cancellationToken: cancellationToken); - - if (options.ChatOptions?.Tools is { Count: > 0 } && (toolDefinitionsAndResources.FunctionToolsAndOtherTools is null || options.ChatOptions.Tools.Count != toolDefinitionsAndResources.FunctionToolsAndOtherTools.Count)) - { - options = options.Clone(); - options.ChatOptions!.Tools = toolDefinitionsAndResources.FunctionToolsAndOtherTools; - } - - // Get a local proxy for the agent to work with. - return persistentAgentsClient.GetAIAgent(createPersistentAgentResponse.Value.Id, options, clientFactory: clientFactory, services: services, cancellationToken: cancellationToken); - } - /// /// Creates a new server side agent using the provided . /// diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs index 8e03a33be3..9db5fad7d3 100644 --- a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs @@ -27,7 +27,7 @@ namespace Azure.AI.Projects; public static partial class AzureAIProjectChatClientExtensions { /// - /// Retrieves an existing server side agent, wrapped as a using the provided . + /// Uses an existing server side agent, wrapped as a using the provided and . /// /// The to create the with. Cannot be . /// The representing the name and version of the server side agent to create a for. Cannot be . @@ -38,10 +38,10 @@ public static partial class AzureAIProjectChatClientExtensions /// Thrown when or is . /// The agent with the specified name was not found. /// - /// When retrieving an agent by using an , minimal information will be available about the agent in the instance level, and any logic that relies + /// When instantiating a by using an , minimal information will be available about the agent in the instance level, and any logic that relies /// on to retrieve information about the agent like will receive as the result. /// - public static ChatClientAgent GetAIAgent( + public static ChatClientAgent AsAIAgent( this AIProjectClient aiProjectClient, AgentReference agentReference, IList? tools = null, @@ -52,7 +52,7 @@ public static ChatClientAgent GetAIAgent( Throw.IfNull(agentReference); ThrowIfInvalidAgentName(agentReference.Name); - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentReference, new ChatClientAgentOptions() @@ -65,40 +65,6 @@ public static ChatClientAgent GetAIAgent( services); } - /// - /// Retrieves an existing server side agent, wrapped as a using the provided . - /// - /// The to create the with. Cannot be . - /// The name of the server side agent to create a for. Cannot be or whitespace. - /// The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations based on the latest version of the named Azure AI Agent. - /// Thrown when or is . - /// Thrown when is empty or whitespace, or when the agent with the specified name was not found. - /// The agent with the specified name was not found. - public static ChatClientAgent GetAIAgent( - this AIProjectClient aiProjectClient, - string name, - IList? tools = null, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - Throw.IfNull(aiProjectClient); - ThrowIfInvalidAgentName(name); - - AgentRecord agentRecord = GetAgentRecordByName(aiProjectClient, name, cancellationToken); - - return AsAIAgent( - aiProjectClient, - agentRecord, - tools, - clientFactory, - services); - } - /// /// Asynchronously retrieves an existing server side agent, wrapped as a using the provided . /// @@ -134,7 +100,7 @@ public static async Task GetAIAgentAsync( } /// - /// Gets a runnable agent instance from the provided agent record. + /// Uses an existing server side agent, wrapped as a using the provided and . /// /// The client used to interact with Azure AI Agents. Cannot be . /// The agent record to be converted. The latest version will be used. Cannot be . @@ -155,7 +121,7 @@ public static ChatClientAgent AsAIAgent( var allowDeclarativeMode = tools is not { Count: > 0 }; - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentRecord, tools, @@ -165,7 +131,7 @@ public static ChatClientAgent AsAIAgent( } /// - /// Gets a runnable agent instance from a containing metadata about an Azure AI Agent. + /// Uses an existing server side agent, wrapped as a using the provided and . /// /// The client used to interact with Azure AI Agents. Cannot be . /// The agent version to be converted. Cannot be . @@ -186,7 +152,7 @@ public static ChatClientAgent AsAIAgent( var allowDeclarativeMode = tools is not { Count: > 0 }; - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentVersion, tools, @@ -196,47 +162,7 @@ public static ChatClientAgent AsAIAgent( } /// - /// Creates a new Prompt AI Agent using the provided and options. - /// - /// The client used to manage and interact with AI agents. Cannot be . - /// The options for creating the agent. Cannot be . - /// A factory function to customize the creation of the chat client used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// A to cancel the operation if needed. - /// A instance that can be used to perform operations on the newly created agent. - /// Thrown when or is . - public static ChatClientAgent GetAIAgent( - this AIProjectClient aiProjectClient, - ChatClientAgentOptions options, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - Throw.IfNull(aiProjectClient); - Throw.IfNull(options); - - if (string.IsNullOrWhiteSpace(options.Name)) - { - throw new ArgumentException("Agent name must be provided in the options.Name property", nameof(options)); - } - - ThrowIfInvalidAgentName(options.Name); - - AgentRecord agentRecord = GetAgentRecordByName(aiProjectClient, options.Name, cancellationToken); - var agentVersion = agentRecord.Versions.Latest; - - var agentOptions = CreateChatClientAgentOptions(agentVersion, options, requireInvocableTools: true); - - return CreateChatClientAgent( - aiProjectClient, - agentVersion, - agentOptions, - clientFactory, - services); - } - - /// - /// Creates a new Prompt AI Agent using the provided and options. + /// Asynchronously retrieves an existing server side agent, wrapped as a using the provided . /// /// The client used to manage and interact with AI agents. Cannot be . /// The options for creating the agent. Cannot be . @@ -267,7 +193,7 @@ public static async Task GetAIAgentAsync( var agentOptions = CreateChatClientAgentOptions(agentVersion, options, requireInvocableTools: true); - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentVersion, agentOptions, @@ -276,49 +202,7 @@ public static async Task GetAIAgentAsync( } /// - /// Creates a new Prompt AI agent using the specified configuration parameters. - /// - /// The client used to manage and interact with AI agents. Cannot be . - /// The name for the agent. - /// The name of the model to use for the agent. Cannot be or whitespace. - /// The instructions that guide the agent's behavior. Cannot be or whitespace. - /// The description for the agent. - /// The tools to use when interacting with the agent, this is required when using prompt agent definitions with tools. - /// A factory function to customize the creation of the chat client used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// A token to monitor for cancellation requests. - /// A instance that can be used to perform operations on the newly created agent. - /// Thrown when , , or is . - /// Thrown when or is empty or whitespace. - /// When using prompt agent definitions with tools the parameter needs to be provided. - public static ChatClientAgent CreateAIAgent( - this AIProjectClient aiProjectClient, - string name, - string model, - string instructions, - string? description = null, - IList? tools = null, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - Throw.IfNull(aiProjectClient); - ThrowIfInvalidAgentName(name); - Throw.IfNullOrWhitespace(model); - Throw.IfNullOrWhitespace(instructions); - - return CreateAIAgent( - aiProjectClient, - name, - tools, - new AgentVersionCreationOptions(new PromptAgentDefinition(model) { Instructions = instructions }) { Description = description }, - clientFactory, - services, - cancellationToken); - } - - /// - /// Creates a new Prompt AI agent using the specified configuration parameters. + /// Creates a new Prompt AI agent in the Foundry service using the specified configuration parameters, and exposes it as a . /// /// The client used to manage and interact with AI agents. Cannot be . /// The name for the agent. @@ -360,73 +244,7 @@ public static Task CreateAIAgentAsync( } /// - /// Creates a new Prompt AI Agent using the provided and options. - /// - /// The client used to manage and interact with AI agents. Cannot be . - /// The name of the model to use for the agent. Cannot be or whitespace. - /// The options for creating the agent. Cannot be . - /// A factory function to customize the creation of the chat client used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// A to cancel the operation if needed. - /// A instance that can be used to perform operations on the newly created agent. - /// Thrown when or is . - /// Thrown when is empty or whitespace, or when the agent name is not provided in the options. - public static ChatClientAgent CreateAIAgent( - this AIProjectClient aiProjectClient, - string model, - ChatClientAgentOptions options, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - Throw.IfNull(aiProjectClient); - Throw.IfNull(options); - Throw.IfNullOrWhitespace(model); - const bool RequireInvocableTools = true; - - if (string.IsNullOrWhiteSpace(options.Name)) - { - throw new ArgumentException("Agent name must be provided in the options.Name property", nameof(options)); - } - - ThrowIfInvalidAgentName(options.Name); - - PromptAgentDefinition agentDefinition = new(model) - { - Instructions = options.ChatOptions?.Instructions, - Temperature = options.ChatOptions?.Temperature, - TopP = options.ChatOptions?.TopP, - TextOptions = new() { TextFormat = ToOpenAIResponseTextFormat(options.ChatOptions?.ResponseFormat, options.ChatOptions) } - }; - - // Attempt to capture breaking glass options from the raw representation factory that match the agent definition. - if (options.ChatOptions?.RawRepresentationFactory?.Invoke(new NoOpChatClient()) is CreateResponseOptions respCreationOptions) - { - agentDefinition.ReasoningOptions = respCreationOptions.ReasoningOptions; - } - - ApplyToolsToAgentDefinition(agentDefinition, options.ChatOptions?.Tools); - - AgentVersionCreationOptions? creationOptions = new(agentDefinition); - if (!string.IsNullOrWhiteSpace(options.Description)) - { - creationOptions.Description = options.Description; - } - - AgentVersion agentVersion = CreateAgentVersionWithProtocol(aiProjectClient, options.Name, creationOptions, cancellationToken); - - var agentOptions = CreateChatClientAgentOptions(agentVersion, options, RequireInvocableTools); - - return CreateChatClientAgent( - aiProjectClient, - agentVersion, - agentOptions, - clientFactory, - services); - } - - /// - /// Creates a new Prompt AI Agent using the provided and options. + /// Creates a new Prompt AI agent in the Foundry service using the specified configuration parameters, and exposes it as a . /// /// The client used to manage and interact with AI agents. Cannot be . /// The name of the model to use for the agent. Cannot be or whitespace. @@ -483,7 +301,7 @@ public static async Task CreateAIAgentAsync( var agentOptions = CreateChatClientAgentOptions(agentVersion, options, RequireInvocableTools); - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentVersion, agentOptions, @@ -492,42 +310,7 @@ public static async Task CreateAIAgentAsync( } /// - /// Creates a new AI agent using the specified agent definition and optional configuration parameters. - /// - /// The client used to manage and interact with AI agents. Cannot be . - /// The name for the agent. - /// Settings that control the creation of the agent. - /// A factory function to customize the creation of the chat client used by the agent. - /// A token to monitor for cancellation requests. - /// A instance that can be used to perform operations on the newly created agent. - /// Thrown when or is . - /// - /// When using this extension method with a the tools are only declarative and not invocable. - /// Invocation of any in-process tools will need to be handled manually. - /// - public static ChatClientAgent CreateAIAgent( - this AIProjectClient aiProjectClient, - string name, - AgentVersionCreationOptions creationOptions, - Func? clientFactory = null, - CancellationToken cancellationToken = default) - { - Throw.IfNull(aiProjectClient); - ThrowIfInvalidAgentName(name); - Throw.IfNull(creationOptions); - - return CreateAIAgent( - aiProjectClient, - name, - tools: null, - creationOptions, - clientFactory, - services: null, - cancellationToken); - } - - /// - /// Asynchronously creates a new AI agent using the specified agent definition and optional configuration + /// Creates a new Prompt AI agent in the Foundry service using the specified configuration parameters, and exposes it as a . /// parameters. /// /// The client used to manage and interact with AI agents. Cannot be . @@ -566,18 +349,6 @@ public static Task CreateAIAgentAsync( private static readonly ModelReaderWriterOptions s_modelWriterOptionsWire = new("W"); - /// - /// Retrieves an agent record by name using the Protocol method with user-agent header. - /// - private static AgentRecord GetAgentRecordByName(AIProjectClient aiProjectClient, string agentName, CancellationToken cancellationToken) - { - ClientResult protocolResponse = aiProjectClient.Agents.GetAgent(agentName, cancellationToken.ToRequestOptions(false)); - var rawResponse = protocolResponse.GetRawResponse(); - AgentRecord? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default); - return ClientResult.FromOptionalValue(result, rawResponse).Value! - ?? throw new InvalidOperationException($"Agent with name '{agentName}' not found."); - } - /// /// Asynchronously retrieves an agent record by name using the Protocol method with user-agent header. /// @@ -590,19 +361,6 @@ private static async Task GetAgentRecordByNameAsync(AIProjectClient ?? throw new InvalidOperationException($"Agent with name '{agentName}' not found."); } - /// - /// Creates an agent version using the Protocol method with user-agent header. - /// - private static AgentVersion CreateAgentVersionWithProtocol(AIProjectClient aiProjectClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken) - { - using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIProjectsContext.Default)); - ClientResult protocolResponse = aiProjectClient.Agents.CreateAgentVersion(agentName, protocolRequest, cancellationToken.ToRequestOptions(false)); - - var rawResponse = protocolResponse.GetRawResponse(); - AgentVersion? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default); - return ClientResult.FromValue(result, rawResponse).Value!; - } - /// /// Asynchronously creates an agent version using the Protocol method with user-agent header. /// @@ -616,33 +374,6 @@ private static async Task CreateAgentVersionWithProtocolAsync(AIPr return ClientResult.FromValue(result, rawResponse).Value!; } - private static ChatClientAgent CreateAIAgent( - this AIProjectClient aiProjectClient, - string name, - IList? tools, - AgentVersionCreationOptions creationOptions, - Func? clientFactory, - IServiceProvider? services, - CancellationToken cancellationToken) - { - var allowDeclarativeMode = tools is not { Count: > 0 }; - - if (!allowDeclarativeMode) - { - ApplyToolsToAgentDefinition(creationOptions.Definition, tools); - } - - AgentVersion agentVersion = CreateAgentVersionWithProtocol(aiProjectClient, name, creationOptions, cancellationToken); - - return CreateChatClientAgent( - aiProjectClient, - agentVersion, - tools, - clientFactory, - !allowDeclarativeMode, - services); - } - private static async Task CreateAIAgentAsync( this AIProjectClient aiProjectClient, string name, @@ -661,7 +392,7 @@ private static async Task CreateAIAgentAsync( AgentVersion agentVersion = await CreateAgentVersionWithProtocolAsync(aiProjectClient, name, creationOptions, cancellationToken).ConfigureAwait(false); - return CreateChatClientAgent( + return AsChatClientAgent( aiProjectClient, agentVersion, tools, @@ -671,7 +402,7 @@ private static async Task CreateAIAgentAsync( } /// This method creates an with the specified ChatClientAgentOptions. - private static ChatClientAgent CreateChatClientAgent( + private static ChatClientAgent AsChatClientAgent( AIProjectClient aiProjectClient, AgentVersion agentVersion, ChatClientAgentOptions agentOptions, @@ -689,7 +420,7 @@ private static ChatClientAgent CreateChatClientAgent( } /// This method creates an with the specified ChatClientAgentOptions. - private static ChatClientAgent CreateChatClientAgent( + private static ChatClientAgent AsChatClientAgent( AIProjectClient aiProjectClient, AgentRecord agentRecord, ChatClientAgentOptions agentOptions, @@ -707,7 +438,7 @@ private static ChatClientAgent CreateChatClientAgent( } /// This method creates an with the specified ChatClientAgentOptions. - private static ChatClientAgent CreateChatClientAgent( + private static ChatClientAgent AsChatClientAgent( AIProjectClient aiProjectClient, AgentReference agentReference, ChatClientAgentOptions agentOptions, @@ -725,14 +456,14 @@ private static ChatClientAgent CreateChatClientAgent( } /// This method creates an with a auto-generated ChatClientAgentOptions from the specified configuration parameters. - private static ChatClientAgent CreateChatClientAgent( + private static ChatClientAgent AsChatClientAgent( AIProjectClient AIProjectClient, AgentVersion agentVersion, IList? tools, Func? clientFactory, bool requireInvocableTools, IServiceProvider? services) - => CreateChatClientAgent( + => AsChatClientAgent( AIProjectClient, agentVersion, CreateChatClientAgentOptions(agentVersion, new ChatOptions() { Tools = tools }, requireInvocableTools), @@ -740,14 +471,14 @@ private static ChatClientAgent CreateChatClientAgent( services); /// This method creates an with a auto-generated ChatClientAgentOptions from the specified configuration parameters. - private static ChatClientAgent CreateChatClientAgent( + private static ChatClientAgent AsChatClientAgent( AIProjectClient AIProjectClient, AgentRecord agentRecord, IList? tools, Func? clientFactory, bool requireInvocableTools, IServiceProvider? services) - => CreateChatClientAgent( + => AsChatClientAgent( AIProjectClient, agentRecord, CreateChatClientAgentOptions(agentRecord.Versions.Latest, new ChatOptions() { Tools = tools }, requireInvocableTools), diff --git a/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs index 291ff56091..a03f7e7455 100644 --- a/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs @@ -93,39 +93,6 @@ public static ChatClientAgent AsAIAgent( }, services: services); } - /// - /// Retrieves an existing server side agent, wrapped as a using the provided . - /// - /// The to create the with. - /// The ID of the server side agent to create a for. - /// Options that should apply to all runs of the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the assistant agent. - [Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")] - public static ChatClientAgent GetAIAgent( - this AssistantClient assistantClient, - string agentId, - ChatOptions? chatOptions = null, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (assistantClient is null) - { - throw new ArgumentNullException(nameof(assistantClient)); - } - - if (string.IsNullOrWhiteSpace(agentId)) - { - throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); - } - - var assistant = assistantClient.GetAssistant(agentId, cancellationToken); - return assistantClient.AsAIAgent(assistant, chatOptions, clientFactory, services); - } - /// /// Retrieves an existing server side agent, wrapped as a using the provided . /// @@ -245,46 +212,6 @@ public static ChatClientAgent AsAIAgent( return new ChatClientAgent(chatClient, mergedOptions, services: services); } - /// - /// Retrieves an existing server side agent, wrapped as a using the provided . - /// - /// The to create the with. - /// The ID of the server side agent to create a for. - /// Full set of options to configure the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// The to monitor for cancellation requests. The default is . - /// A instance that can be used to perform operations on the assistant agent. - /// or is . - /// is empty or whitespace. - [Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")] - public static ChatClientAgent GetAIAgent( - this AssistantClient assistantClient, - string agentId, - ChatClientAgentOptions options, - Func? clientFactory = null, - IServiceProvider? services = null, - CancellationToken cancellationToken = default) - { - if (assistantClient is null) - { - throw new ArgumentNullException(nameof(assistantClient)); - } - - if (string.IsNullOrWhiteSpace(agentId)) - { - throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); - } - - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } - - var assistant = assistantClient.GetAssistant(agentId, cancellationToken); - return assistantClient.AsAIAgent(assistant, options, clientFactory, services); - } - /// /// Retrieves an existing server side agent, wrapped as a using the provided . /// @@ -325,111 +252,6 @@ public static async Task GetAIAgentAsync( return assistantClient.AsAIAgent(assistantResponse, options, clientFactory, services); } - /// - /// Creates an AI agent from an using the OpenAI Assistant API. - /// - /// The OpenAI to use for the agent. - /// The model identifier to use (e.g., "gpt-4"). - /// Optional system instructions that define the agent's behavior and personality. - /// Optional name for the agent for identification purposes. - /// Optional description of the agent's capabilities and purpose. - /// Optional collection of AI tools that the agent can use during conversations. - /// Provides a way to customize the creation of the underlying used by the agent. - /// Optional logger factory for enabling logging within the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// An instance backed by the OpenAI Assistant service. - /// Thrown when or is . - /// Thrown when is empty or whitespace. - [Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")] - public static ChatClientAgent CreateAIAgent( - this AssistantClient client, - string model, - string? instructions = null, - string? name = null, - string? description = null, - IList? tools = null, - Func? clientFactory = null, - ILoggerFactory? loggerFactory = null, - IServiceProvider? services = null) => - client.CreateAIAgent( - model, - new ChatClientAgentOptions() - { - Name = name, - Description = description, - ChatOptions = tools is null && string.IsNullOrWhiteSpace(instructions) ? null : new ChatOptions() - { - Tools = tools, - Instructions = instructions - } - }, - clientFactory, - loggerFactory, - services); - - /// - /// Creates an AI agent from an using the OpenAI Assistant API. - /// - /// The OpenAI to use for the agent. - /// The model identifier to use (e.g., "gpt-4"). - /// Full set of options to configure the agent. - /// Provides a way to customize the creation of the underlying used by the agent. - /// Optional logger factory for enabling logging within the agent. - /// An optional to use for resolving services required by the instances being invoked. - /// An instance backed by the OpenAI Assistant service. - /// Thrown when or or is . - /// Thrown when is empty or whitespace. - [Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")] - public static ChatClientAgent CreateAIAgent( - this AssistantClient client, - string model, - ChatClientAgentOptions options, - Func? clientFactory = null, - ILoggerFactory? loggerFactory = null, - IServiceProvider? services = null) - { - Throw.IfNull(client); - Throw.IfNullOrEmpty(model); - Throw.IfNull(options); - - var assistantOptions = new AssistantCreationOptions() - { - Name = options.Name, - Description = options.Description, - Instructions = options.ChatOptions?.Instructions, - }; - - // Convert AITools to ToolDefinitions and ToolResources - var toolDefinitionsAndResources = ConvertAIToolsToToolDefinitions(options.ChatOptions?.Tools); - if (toolDefinitionsAndResources.ToolDefinitions is { Count: > 0 }) - { - toolDefinitionsAndResources.ToolDefinitions.ForEach(x => assistantOptions.Tools.Add(x)); - } - - if (toolDefinitionsAndResources.ToolResources is not null) - { - assistantOptions.ToolResources = toolDefinitionsAndResources.ToolResources; - } - - // Create the assistant in the assistant service. - var assistantCreateResult = client.CreateAssistant(model, assistantOptions); - var assistantId = assistantCreateResult.Value.Id; - - // Build the local agent object. - var chatClient = client.AsIChatClient(assistantId); - if (clientFactory is not null) - { - chatClient = clientFactory(chatClient); - } - - var agentOptions = options.Clone(); - agentOptions.Id = assistantId; - options.ChatOptions ??= new ChatOptions(); - options.ChatOptions!.Tools = toolDefinitionsAndResources.FunctionToolsAndOtherTools; - - return new ChatClientAgent(chatClient, agentOptions, loggerFactory, services); - } - /// /// Creates an AI agent from an using the OpenAI Assistant API. /// diff --git a/dotnet/tests/AzureAI.IntegrationTests/AIProjectClientCreateTests.cs b/dotnet/tests/AzureAI.IntegrationTests/AIProjectClientCreateTests.cs index f626736418..d70d3d949d 100644 --- a/dotnet/tests/AzureAI.IntegrationTests/AIProjectClientCreateTests.cs +++ b/dotnet/tests/AzureAI.IntegrationTests/AIProjectClientCreateTests.cs @@ -22,9 +22,7 @@ public class AIProjectClientCreateTests [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string createMechanism) { // Arrange. @@ -43,20 +41,9 @@ public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string create Description = AgentDescription, ChatOptions = new() { Instructions = AgentInstructions } }), - "CreateWithChatClientAgentOptionsSync" => this._client.CreateAIAgent( - model: s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - Name = AgentName, - Description = AgentDescription, - ChatOptions = new() { Instructions = AgentInstructions } - }), "CreateWithFoundryOptionsAsync" => await this._client.CreateAIAgentAsync( name: AgentName, creationOptions: new AgentVersionCreationOptions(new PromptAgentDefinition(s_config.DeploymentName) { Instructions = AgentInstructions }) { Description = AgentDescription }), - "CreateWithFoundryOptionsSync" => this._client.CreateAIAgent( - name: AgentName, - creationOptions: new AgentVersionCreationOptions(new PromptAgentDefinition(s_config.DeploymentName) { Instructions = AgentInstructions }) { Description = AgentDescription }), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -84,9 +71,7 @@ public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string create [Theory(Skip = "For manual testing only")] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithVectorStoresAsync(string createMechanism) { // Arrange. @@ -120,21 +105,11 @@ You are a helpful agent that can help fetch data from files you know about. name: AgentName, instructions: AgentInstructions, tools: [new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreMetadata.Value.Id)] }]), - "CreateWithChatClientAgentOptionsSync" => this._client.CreateAIAgent( - model: s_config.DeploymentName, - name: AgentName, - instructions: AgentInstructions, - tools: [new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreMetadata.Value.Id)] }]), "CreateWithFoundryOptionsAsync" => await this._client.CreateAIAgentAsync( model: s_config.DeploymentName, name: AgentName, instructions: AgentInstructions, tools: [ResponseTool.CreateFileSearchTool(vectorStoreIds: [vectorStoreMetadata.Value.Id]).AsAITool()]), - "CreateWithFoundryOptionsSync" => this._client.CreateAIAgent( - model: s_config.DeploymentName, - name: AgentName, - instructions: AgentInstructions, - tools: [ResponseTool.CreateFileSearchTool(vectorStoreIds: [vectorStoreMetadata.Value.Id]).AsAITool()]), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -157,9 +132,7 @@ You are a helpful agent that can help fetch data from files you know about. [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithCodeInterpreterAsync(string createMechanism) { // Arrange. @@ -192,22 +165,12 @@ and report the SECRET_NUMBER value it prints. Respond only with the number. name: AgentName, instructions: AgentInstructions, tools: [new HostedCodeInterpreterTool() { Inputs = [new HostedFileContent(uploadedCodeFile.Id)] }]), - "CreateWithChatClientAgentOptionsSync" => this._client.CreateAIAgent( - model: s_config.DeploymentName, - name: AgentName, - instructions: AgentInstructions, - tools: [new HostedCodeInterpreterTool() { Inputs = [new HostedFileContent(uploadedCodeFile.Id)] }]), // Foundry (definitions + resources provided directly) "CreateWithFoundryOptionsAsync" => await this._client.CreateAIAgentAsync( model: s_config.DeploymentName, name: AgentName, instructions: AgentInstructions, tools: [ResponseTool.CreateCodeInterpreterTool(new CodeInterpreterToolContainer(CodeInterpreterToolContainerConfiguration.CreateAutomaticContainerConfiguration([uploadedCodeFile.Id]))).AsAITool()]), - "CreateWithFoundryOptionsSync" => this._client.CreateAIAgent( - model: s_config.DeploymentName, - name: AgentName, - instructions: AgentInstructions, - tools: [ResponseTool.CreateCodeInterpreterTool(new CodeInterpreterToolContainer(CodeInterpreterToolContainerConfiguration.CreateAutomaticContainerConfiguration([uploadedCodeFile.Id]))).AsAITool()]), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -229,7 +192,6 @@ and report the SECRET_NUMBER value it prints. Respond only with the number. [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] public async Task CreateAgent_CreatesAgentWithAIFunctionToolsAsync(string createMechanism) { // Arrange. @@ -248,13 +210,6 @@ public async Task CreateAgent_CreatesAgentWithAIFunctionToolsAsync(string create Name = AgentName, ChatOptions = new() { Instructions = AgentInstructions, Tools = [weatherFunction] } }), - "CreateWithChatClientAgentOptionsSync" => this._client.CreateAIAgent( - s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - Name = AgentName, - ChatOptions = new() { Instructions = AgentInstructions, Tools = [weatherFunction] } - }), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; diff --git a/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs b/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs index a10cc11d79..05b87539da 100644 --- a/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs +++ b/dotnet/tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistentCreateTests.cs @@ -20,9 +20,7 @@ public class AzureAIAgentsPersistentCreateTests [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string createMechanism) { // Arrange. @@ -41,24 +39,11 @@ public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string create Name = AgentName, Description = AgentDescription }), - "CreateWithChatClientAgentOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - ChatOptions = new() { Instructions = AgentInstructions }, - Name = AgentName, - Description = AgentDescription - }), "CreateWithFoundryOptionsAsync" => await this._persistentAgentsClient.CreateAIAgentAsync( s_config.DeploymentName, instructions: AgentInstructions, name: AgentName, description: AgentDescription), - "CreateWithFoundryOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - instructions: AgentInstructions, - name: AgentName, - description: AgentDescription), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -85,9 +70,7 @@ public async Task CreateAgent_CreatesAgentWithCorrectMetadataAsync(string create [Theory(Skip = "For manual testing only")] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithVectorStoresAsync(string createMechanism) { // Arrange. @@ -125,26 +108,11 @@ You are a helpful agent that can help fetch data from files you know about. Tools = [new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreMetadata.Value.Id)] }] } }), - "CreateWithChatClientAgentOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - ChatOptions = new() - { - Instructions = AgentInstructions, - Tools = [new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreMetadata.Value.Id)] }] - } - }), "CreateWithFoundryOptionsAsync" => await this._persistentAgentsClient.CreateAIAgentAsync( s_config.DeploymentName, instructions: AgentInstructions, tools: [new FileSearchToolDefinition()], toolResources: new ToolResources() { FileSearch = new([vectorStoreMetadata.Value.Id], null) }), - "CreateWithFoundryOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - instructions: AgentInstructions, - tools: [new FileSearchToolDefinition()], - toolResources: new ToolResources() { FileSearch = new([vectorStoreMetadata.Value.Id], null) }), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -167,9 +135,7 @@ You are a helpful agent that can help fetch data from files you know about. [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] [InlineData("CreateWithFoundryOptionsAsync")] - [InlineData("CreateWithFoundryOptionsSync")] public async Task CreateAgent_CreatesAgentWithCodeInterpreterAsync(string createMechanism) { // Arrange. @@ -205,26 +171,11 @@ and report the SECRET_NUMBER value it prints. Respond only with the number. Tools = [new HostedCodeInterpreterTool() { Inputs = [new HostedFileContent(uploadedCodeFile.Id)] }] } }), - "CreateWithChatClientAgentOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - ChatOptions = new() - { - Instructions = AgentInstructions, - Tools = [new HostedCodeInterpreterTool() { Inputs = [new HostedFileContent(uploadedCodeFile.Id)] }] - } - }), "CreateWithFoundryOptionsAsync" => await this._persistentAgentsClient.CreateAIAgentAsync( s_config.DeploymentName, instructions: AgentInstructions, tools: [new CodeInterpreterToolDefinition()], toolResources: new ToolResources() { CodeInterpreter = toolResource }), - "CreateWithFoundryOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - instructions: AgentInstructions, - tools: [new CodeInterpreterToolDefinition()], - toolResources: new ToolResources() { CodeInterpreter = toolResource }), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; @@ -246,7 +197,6 @@ and report the SECRET_NUMBER value it prints. Respond only with the number. [Theory] [InlineData("CreateWithChatClientAgentOptionsAsync")] - [InlineData("CreateWithChatClientAgentOptionsSync")] public async Task CreateAgent_CreatesAgentWithAIFunctionToolsAsync(string createMechanism) { // Arrange. @@ -267,16 +217,6 @@ public async Task CreateAgent_CreatesAgentWithAIFunctionToolsAsync(string create Tools = [weatherFunction] } }), - "CreateWithChatClientAgentOptionsSync" => this._persistentAgentsClient.CreateAIAgent( - s_config.DeploymentName, - options: new ChatClientAgentOptions() - { - ChatOptions = new() - { - Instructions = AgentInstructions, - Tools = [weatherFunction] - } - }), _ => throw new InvalidOperationException($"Unknown create mechanism: {createMechanism}") }; diff --git a/dotnet/tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Extensions/PersistentAgentsClientExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Extensions/PersistentAgentsClientExtensionsTests.cs index a3d3be27fe..51de9ac64e 100644 --- a/dotnet/tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Extensions/PersistentAgentsClientExtensionsTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Extensions/PersistentAgentsClientExtensionsTests.cs @@ -18,44 +18,6 @@ namespace Microsoft.Agents.AI.AzureAI.Persistent.UnitTests.Extensions; public sealed class PersistentAgentsClientExtensionsTests { - /// - /// Verify that GetAIAgent throws ArgumentNullException when client is null. - /// - [Fact] - public void GetAIAgent_WithNullClient_ThrowsArgumentNullException() - { - // Act & Assert - var exception = Assert.Throws(() => - ((PersistentAgentsClient)null!).GetAIAgent("test-agent")); - - Assert.Equal("persistentAgentsClient", exception.ParamName); - } - - /// - /// Verify that GetAIAgent throws ArgumentException when agentId is null or whitespace. - /// - [Fact] - public void GetAIAgent_WithNullOrWhitespaceAgentId_ThrowsArgumentException() - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - null agentId - var exception1 = Assert.Throws(() => - mockClient.Object.GetAIAgent(null!)); - Assert.Equal("agentId", exception1.ParamName); - - // Act & Assert - empty agentId - var exception2 = Assert.Throws(() => - mockClient.Object.GetAIAgent("")); - Assert.Equal("agentId", exception2.ParamName); - - // Act & Assert - whitespace agentId - var exception3 = Assert.Throws(() => - mockClient.Object.GetAIAgent(" ")); - Assert.Equal("agentId", exception3.ParamName); - } - /// /// Verify that GetAIAgentAsync throws ArgumentNullException when client is null. /// @@ -94,19 +56,6 @@ public async Task GetAIAgentAsync_WithNullOrWhitespaceAgentId_ThrowsArgumentExce Assert.Equal("agentId", exception3.ParamName); } - /// - /// Verify that CreateAIAgent throws ArgumentNullException when client is null. - /// - [Fact] - public void CreateAIAgent_WithNullClient_ThrowsArgumentNullException() - { - // Act & Assert - var exception = Assert.Throws(() => - ((PersistentAgentsClient)null!).CreateAIAgent("test-model")); - - Assert.Equal("persistentAgentsClient", exception.ParamName); - } - /// /// Verify that CreateAIAgentAsync throws ArgumentNullException when client is null. /// @@ -124,14 +73,14 @@ public async Task CreateAIAgentAsync_WithNullClient_ThrowsArgumentNullExceptionA /// Verify that GetAIAgent with clientFactory parameter correctly applies the factory. /// [Fact] - public void GetAIAgent_WithClientFactory_AppliesFactoryCorrectly() + public async Task GetAIAgentAsync_WithClientFactory_AppliesFactoryCorrectlyAsync() { // Arrange var client = CreateFakePersistentAgentsClient(); TestChatClient? testChatClient = null; // Act - var agent = client.GetAIAgent( + var agent = await client.GetAIAgentAsync( agentId: "test-agent-id", clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); @@ -146,13 +95,13 @@ public void GetAIAgent_WithClientFactory_AppliesFactoryCorrectly() /// Verify that GetAIAgent without clientFactory works normally. /// [Fact] - public void GetAIAgent_WithoutClientFactory_WorksNormally() + public async Task GetAIAgentAsync_WithoutClientFactory_WorksNormallyAsync() { // Arrange var client = CreateFakePersistentAgentsClient(); // Act - var agent = client.GetAIAgent(agentId: "test-agent-id"); + var agent = await client.GetAIAgentAsync(agentId: "test-agent-id"); // Assert Assert.NotNull(agent); @@ -164,13 +113,13 @@ public void GetAIAgent_WithoutClientFactory_WorksNormally() /// Verify that GetAIAgent with null clientFactory works normally. /// [Fact] - public void GetAIAgent_WithNullClientFactory_WorksNormally() + public async Task GetAIAgentAsync_WithNullClientFactory_WorksNormallyAsync() { // Arrange PersistentAgentsClient client = CreateFakePersistentAgentsClient(); // Act - var agent = client.GetAIAgent(agentId: "test-agent-id", clientFactory: null); + var agent = await client.GetAIAgentAsync(agentId: "test-agent-id", clientFactory: null); // Assert Assert.NotNull(agent); @@ -178,29 +127,6 @@ public void GetAIAgent_WithNullClientFactory_WorksNormally() Assert.Null(retrievedTestClient); } - /// - /// Verify that CreateAIAgent with clientFactory parameter correctly applies the factory. - /// - [Fact] - public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly() - { - // Arrange - // Arrange - var client = CreateFakePersistentAgentsClient(); - TestChatClient? testChatClient = null; - - // Act - var agent = client.CreateAIAgent( - model: "test-model", - clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); - - // Assert - Assert.NotNull(agent); - var retrievedTestClient = agent.GetService(); - Assert.NotNull(retrievedTestClient); - Assert.Same(testChatClient, retrievedTestClient); - } - /// /// Verify that CreateAIAgentAsync with clientFactory parameter correctly applies the factory. /// @@ -223,42 +149,6 @@ public async Task CreateAIAgentAsync_WithClientFactory_AppliesFactoryCorrectlyAs Assert.Same(testChatClient, retrievedTestClient); } - /// - /// Verify that CreateAIAgent without clientFactory works normally. - /// - [Fact] - public void CreateAIAgent_WithoutClientFactory_WorksNormally() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - - // Act - var agent = client.CreateAIAgent(model: "test-model"); - - // Assert - Assert.NotNull(agent); - var retrievedTestClient = agent.GetService(); - Assert.Null(retrievedTestClient); - } - - /// - /// Verify that CreateAIAgent with null clientFactory works normally. - /// - [Fact] - public void CreateAIAgent_WithNullClientFactory_WorksNormally() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - - // Act - var agent = client.CreateAIAgent(model: "test-model", clientFactory: null); - - // Assert - Assert.NotNull(agent); - var retrievedTestClient = agent.GetService(); - Assert.Null(retrievedTestClient); - } - /// /// Verify that CreateAIAgent without clientFactory works normally. /// @@ -372,33 +262,6 @@ public void GetAIAgent_WithPersistentAgentAndOptionsWithNullFields_FallsBackToAg Assert.Equal("Original Instructions", agent.Instructions); } - /// - /// Verify that GetAIAgent with agentId and options works correctly. - /// - [Fact] - public void GetAIAgent_WithAgentIdAndOptions_WorksCorrectly() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - const string AgentId = "agent_abc123"; - - var options = new ChatClientAgentOptions - { - Name = "Override Name", - Description = "Override Description", - ChatOptions = new() { Instructions = "Override Instructions" } - }; - - // Act - var agent = client.GetAIAgent(AgentId, options); - - // Assert - Assert.NotNull(agent); - Assert.Equal("Override Name", agent.Name); - Assert.Equal("Override Description", agent.Description); - Assert.Equal("Override Instructions", agent.Instructions); - } - /// /// Verify that GetAIAgentAsync with agentId and options works correctly. /// @@ -509,23 +372,6 @@ public void GetAIAgent_WithNullOptions_ThrowsArgumentNullException() Assert.Equal("options", exception.ParamName); } - /// - /// Verify that GetAIAgent throws ArgumentException when agentId is empty. - /// - [Fact] - public void GetAIAgent_WithOptionsAndEmptyAgentId_ThrowsArgumentException() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - var options = new ChatClientAgentOptions(); - - // Act & Assert - var exception = Assert.Throws(() => - client.GetAIAgent(string.Empty, options)); - - Assert.Equal("agentId", exception.ParamName); - } - /// /// Verify that GetAIAgentAsync throws ArgumentException when agentId is empty. /// @@ -543,33 +389,6 @@ public async Task GetAIAgentAsync_WithOptionsAndEmptyAgentId_ThrowsArgumentExcep Assert.Equal("agentId", exception.ParamName); } - /// - /// Verify that CreateAIAgent with options works correctly. - /// - [Fact] - public void CreateAIAgent_WithOptions_WorksCorrectly() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - const string Model = "test-model"; - - var options = new ChatClientAgentOptions - { - Name = "Test Agent", - Description = "Test description", - ChatOptions = new() { Instructions = "Test instructions" } - }; - - // Act - var agent = client.CreateAIAgent(Model, options); - - // Assert - Assert.NotNull(agent); - Assert.Equal("Test Agent", agent.Name); - Assert.Equal("Test description", agent.Description); - Assert.Equal("Test instructions", agent.Instructions); - } - /// /// Verify that CreateAIAgentAsync with options works correctly. /// @@ -597,38 +416,6 @@ public async Task CreateAIAgentAsync_WithOptions_WorksCorrectlyAsync() Assert.Equal("Test instructions", agent.Instructions); } - /// - /// Verify that CreateAIAgent with options and clientFactory applies the factory correctly. - /// - [Fact] - public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - TestChatClient? testChatClient = null; - const string Model = "test-model"; - - var options = new ChatClientAgentOptions - { - Name = "Test Agent" - }; - - // Act - var agent = client.CreateAIAgent( - Model, - options, - clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); - - // Assert - Assert.NotNull(agent); - Assert.Equal("Test Agent", agent.Name); - - // Verify that the custom chat client can be retrieved from the agent's service collection - var retrievedTestClient = agent.GetService(); - Assert.NotNull(retrievedTestClient); - Assert.Same(testChatClient, retrievedTestClient); - } - /// /// Verify that CreateAIAgentAsync with options and clientFactory applies the factory correctly. /// @@ -661,22 +448,6 @@ public async Task CreateAIAgentAsync_WithOptionsAndClientFactory_AppliesFactoryC Assert.Same(testChatClient, retrievedTestClient); } - /// - /// Verify that CreateAIAgent throws ArgumentNullException when options is null. - /// - [Fact] - public void CreateAIAgent_WithNullOptions_ThrowsArgumentNullException() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - - // Act & Assert - var exception = Assert.Throws(() => - client.CreateAIAgent("test-model", (ChatClientAgentOptions)null!)); - - Assert.Equal("options", exception.ParamName); - } - /// /// Verify that CreateAIAgentAsync throws ArgumentNullException when options is null. /// @@ -693,23 +464,6 @@ public async Task CreateAIAgentAsync_WithNullOptions_ThrowsArgumentNullException Assert.Equal("options", exception.ParamName); } - /// - /// Verify that CreateAIAgent throws ArgumentException when model is empty. - /// - [Fact] - public void CreateAIAgent_WithEmptyModel_ThrowsArgumentException() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - var options = new ChatClientAgentOptions(); - - // Act & Assert - var exception = Assert.Throws(() => - client.CreateAIAgent(string.Empty, options)); - - Assert.Equal("model", exception.ParamName); - } - /// /// Verify that CreateAIAgentAsync throws ArgumentException when model is empty. /// @@ -727,35 +481,6 @@ public async Task CreateAIAgentAsync_WithEmptyModel_ThrowsArgumentExceptionAsync Assert.Equal("model", exception.ParamName); } - /// - /// Verify that CreateAIAgent with services parameter correctly passes it through to the ChatClientAgent. - /// - [Fact] - public void CreateAIAgent_WithServices_PassesServicesToAgent() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - var serviceProvider = new TestServiceProvider(); - const string Model = "test-model"; - - // Act - var agent = client.CreateAIAgent( - Model, - instructions: "Test instructions", - name: "Test Agent", - services: serviceProvider); - - // Assert - Assert.NotNull(agent); - - // Verify the IServiceProvider was passed through to the FunctionInvokingChatClient - var chatClient = agent.GetService(); - Assert.NotNull(chatClient); - var functionInvokingClient = chatClient.GetService(); - Assert.NotNull(functionInvokingClient); - Assert.Same(serviceProvider, GetFunctionInvocationServices(functionInvokingClient)); - } - /// /// Verify that CreateAIAgentAsync with services parameter correctly passes it through to the ChatClientAgent. /// @@ -785,30 +510,6 @@ public async Task CreateAIAgentAsync_WithServices_PassesServicesToAgentAsync() Assert.Same(serviceProvider, GetFunctionInvocationServices(functionInvokingClient)); } - /// - /// Verify that GetAIAgent with services parameter correctly passes it through to the ChatClientAgent. - /// - [Fact] - public void GetAIAgent_WithServices_PassesServicesToAgent() - { - // Arrange - var client = CreateFakePersistentAgentsClient(); - var serviceProvider = new TestServiceProvider(); - - // Act - var agent = client.GetAIAgent("agent_abc123", services: serviceProvider); - - // Assert - Assert.NotNull(agent); - - // Verify the IServiceProvider was passed through to the FunctionInvokingChatClient - var chatClient = agent.GetService(); - Assert.NotNull(chatClient); - var functionInvokingClient = chatClient.GetService(); - Assert.NotNull(functionInvokingClient); - Assert.Same(serviceProvider, GetFunctionInvocationServices(functionInvokingClient)); - } - /// /// Verify that GetAIAgentAsync with services parameter correctly passes it through to the ChatClientAgent. /// @@ -837,7 +538,7 @@ public async Task GetAIAgentAsync_WithServices_PassesServicesToAgentAsync() /// Verify that CreateAIAgent with both clientFactory and services works correctly. /// [Fact] - public void CreateAIAgent_WithClientFactoryAndServices_AppliesBothCorrectly() + public async Task CreateAIAgentAsync_WithClientFactoryAndServices_AppliesBothCorrectlyAsync() { // Arrange var client = CreateFakePersistentAgentsClient(); @@ -846,7 +547,7 @@ public void CreateAIAgent_WithClientFactoryAndServices_AppliesBothCorrectly() const string Model = "test-model"; // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( Model, instructions: "Test instructions", name: "Test Agent", diff --git a/dotnet/tests/Microsoft.Agents.AI.AzureAI.UnitTests/AzureAIProjectChatClientExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.AzureAI.UnitTests/AzureAIProjectChatClientExtensionsTests.cs index 528dc323af..eb2ea449e6 100644 --- a/dotnet/tests/Microsoft.Agents.AI.AzureAI.UnitTests/AzureAIProjectChatClientExtensionsTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.AzureAI.UnitTests/AzureAIProjectChatClientExtensionsTests.cs @@ -180,7 +180,7 @@ public void AsAIAgent_WithAgentVersion_WithClientFactory_AppliesFactoryCorrectly } /// - /// Verify that GetAIAgent with requireInvocableTools=true enforces invocable tools. + /// Verify that AsAIAgent with requireInvocableTools=true enforces invocable tools. /// [Fact] public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsTrue_EnforcesInvocableTools() @@ -202,7 +202,7 @@ public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsTrue_EnforcesInv } /// - /// Verify that GetAIAgent with requireInvocableTools=false allows declarative functions. + /// Verify that AsAIAgent with requireInvocableTools=false allows declarative functions. /// [Fact] public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsFalse_AllowsDeclarativeFunctions() @@ -221,101 +221,6 @@ public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsFalse_AllowsDecl #endregion - #region GetAIAgent(AIProjectClient, ChatClientAgentOptions) Tests - - /// - /// Verify that GetAIAgent with ChatClientAgentOptions throws ArgumentNullException when client is null. - /// - [Fact] - public void GetAIAgent_WithOptions_WithNullClient_ThrowsArgumentNullException() - { - // Arrange - AIProjectClient? client = null; - var options = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act & Assert - var exception = Assert.Throws(() => - client!.GetAIAgent(options)); - - Assert.Equal("aiProjectClient", exception.ParamName); - } - - /// - /// Verify that GetAIAgent with ChatClientAgentOptions throws ArgumentNullException when options is null. - /// - [Fact] - public void GetAIAgent_WithOptions_WithNullOptions_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent((ChatClientAgentOptions)null!)); - - Assert.Equal("options", exception.ParamName); - } - - /// - /// Verify that GetAIAgent with ChatClientAgentOptions throws ArgumentException when options.Name is null. - /// - [Fact] - public void GetAIAgent_WithOptions_WithoutName_ThrowsArgumentException() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - var options = new ChatClientAgentOptions(); - - // Act & Assert - var exception = Assert.Throws(() => - client.GetAIAgent(options)); - - Assert.Contains("Agent name must be provided", exception.Message); - } - - /// - /// Verify that GetAIAgent with ChatClientAgentOptions creates a valid agent. - /// - [Fact] - public void GetAIAgent_WithOptions_CreatesValidAgent() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent"); - var options = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act - var agent = client.GetAIAgent(options); - - // Assert - Assert.NotNull(agent); - Assert.Equal("test-agent", agent.Name); - } - - /// - /// Verify that GetAIAgent with ChatClientAgentOptions and clientFactory applies the factory. - /// - [Fact] - public void GetAIAgent_WithOptions_WithClientFactory_AppliesFactoryCorrectly() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent"); - var options = new ChatClientAgentOptions { Name = "test-agent" }; - TestChatClient? testChatClient = null; - - // Act - var agent = client.GetAIAgent( - options, - clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); - - // Assert - Assert.NotNull(agent); - var retrievedTestClient = agent.GetService(); - Assert.NotNull(retrievedTestClient); - Assert.Same(testChatClient, retrievedTestClient); - } - - #endregion - #region GetAIAgentAsync(AIProjectClient, ChatClientAgentOptions) Tests /// @@ -371,20 +276,20 @@ public async Task GetAIAgentAsync_WithOptions_CreatesValidAgentAsync() #endregion - #region GetAIAgent(AIProjectClient, string) Tests + #region AsAIAgent(AIProjectClient, string) Tests /// /// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null. /// [Fact] - public void GetAIAgent_ByName_WithNullClient_ThrowsArgumentNullException() + public void AsAIAgent_ByName_WithNullClient_ThrowsArgumentNullException() { // Arrange AIProjectClient? client = null; // Act & Assert var exception = Assert.Throws(() => - client!.GetAIAgent("test-agent")); + client!.AsAIAgent("test-agent")); Assert.Equal("aiProjectClient", exception.ParamName); } @@ -393,14 +298,14 @@ public void GetAIAgent_ByName_WithNullClient_ThrowsArgumentNullException() /// Verify that AsAIAgent throws ArgumentNullException when name is null. /// [Fact] - public void GetAIAgent_ByName_WithNullName_ThrowsArgumentNullException() + public void AsAIAgent_ByName_WithNullName_ThrowsArgumentNullException() { // Arrange var mockClient = new Mock(); // Act & Assert var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent((string)null!)); + mockClient.Object.AsAIAgent((string)null!)); Assert.Equal("name", exception.ParamName); } @@ -409,41 +314,18 @@ public void GetAIAgent_ByName_WithNullName_ThrowsArgumentNullException() /// Verify that AsAIAgent throws ArgumentException when name is empty. /// [Fact] - public void GetAIAgent_ByName_WithEmptyName_ThrowsArgumentException() + public void AsAIAgent_ByName_WithEmptyName_ThrowsArgumentException() { // Arrange var mockClient = new Mock(); // Act & Assert var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent(string.Empty)); + mockClient.Object.AsAIAgent(string.Empty)); Assert.Equal("name", exception.ParamName); } - /// - /// Verify that AsAIAgent throws InvalidOperationException when agent is not found. - /// - [Fact] - public void GetAIAgent_ByName_WithNonExistentAgent_ThrowsInvalidOperationException() - { - // Arrange - var mockAgentOperations = new Mock(); - mockAgentOperations - .Setup(c => c.GetAgent(It.IsAny(), It.IsAny())) - .Returns(ClientResult.FromOptionalValue((AgentRecord)null!, new MockPipelineResponse(200, BinaryData.FromString("null")))); - - var mockClient = new Mock(); - mockClient.SetupGet(x => x.Agents).Returns(mockAgentOperations.Object); - mockClient.Setup(x => x.GetConnection(It.IsAny())).Returns(new ClientConnection("fake-connection-id", "http://localhost", ClientPipeline.Create(), CredentialKind.None)); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent("non-existent-agent")); - - Assert.Contains("not found", exception.Message); - } - #endregion #region GetAIAgentAsync(AIProjectClient, string) Tests @@ -578,220 +460,6 @@ public async Task GetAIAgentAsync_WithNameAndTools_CreatesAgentAsync() Assert.IsType(agent); } - #endregion - - #region CreateAIAgent(AIProjectClient, string, string) Tests - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when AIProjectClient is null. - /// - [Fact] - public void CreateAIAgent_WithBasicParams_WithNullClient_ThrowsArgumentNullException() - { - // Arrange - AIProjectClient? client = null; - - // Act & Assert - var exception = Assert.Throws(() => - client!.CreateAIAgent("test-agent", "model", "instructions")); - - Assert.Equal("aiProjectClient", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when name is null. - /// - [Fact] - public void CreateAIAgent_WithBasicParams_WithNullName_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent(null!, "model", "instructions")); - - Assert.Equal("name", exception.ParamName); - } - - #endregion - - #region CreateAIAgent(AIProjectClient, string, AgentDefinition) Tests - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when AIProjectClient is null. - /// - [Fact] - public void CreateAIAgent_WithAgentDefinition_WithNullClient_ThrowsArgumentNullException() - { - // Arrange - AIProjectClient? client = null; - var definition = new PromptAgentDefinition("test-model"); - var options = new AgentVersionCreationOptions(definition); - - // Act & Assert - var exception = Assert.Throws(() => - client!.CreateAIAgent("test-agent", options)); - - Assert.Equal("aiProjectClient", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when name is null. - /// - [Fact] - public void CreateAIAgent_WithAgentDefinition_WithNullName_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - var definition = new PromptAgentDefinition("test-model"); - var options = new AgentVersionCreationOptions(definition); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent(null!, options)); - - Assert.Equal("name", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when creationOptions is null. - /// - [Fact] - public void CreateAIAgent_WithAgentDefinition_WithNullDefinition_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent("test-agent", (AgentVersionCreationOptions)null!)); - - Assert.Equal("creationOptions", exception.ParamName); - } - - #endregion - - #region CreateAIAgent(AIProjectClient, ChatClientAgentOptions, string) Tests - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when AIProjectClient is null. - /// - [Fact] - public void CreateAIAgent_WithOptions_WithNullClient_ThrowsArgumentNullException() - { - // Arrange - AIProjectClient? client = null; - var options = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act & Assert - var exception = Assert.Throws(() => - client!.CreateAIAgent("model", options)); - - Assert.Equal("aiProjectClient", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when options is null. - /// - [Fact] - public void CreateAIAgent_WithOptions_WithNullOptions_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent("model", (ChatClientAgentOptions)null!)); - - Assert.Equal("options", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when model is null. - /// - [Fact] - public void CreateAIAgent_WithOptions_WithNullModel_ThrowsArgumentNullException() - { - // Arrange - var mockClient = new Mock(); - var options = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent(null!, options)); - - Assert.Equal("model", exception.ParamName); - } - - /// - /// Verify that CreateAIAgent throws ArgumentNullException when options.Name is null. - /// - [Fact] - public void CreateAIAgent_WithOptions_WithoutName_ThrowsException() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - var options = new ChatClientAgentOptions(); - - // Act & Assert - var exception = Assert.Throws(() => - client.CreateAIAgent("test-model", options)); - - Assert.Contains("Agent name must be provided", exception.Message); - } - - /// - /// Verify that CreateAIAgent with model and options creates a valid agent. - /// - [Fact] - public void CreateAIAgent_WithModelAndOptions_CreatesValidAgent() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", instructions: "Test instructions"); - var options = new ChatClientAgentOptions - { - Name = "test-agent", - ChatOptions = new() { Instructions = "Test instructions" } - }; - - // Act - var agent = client.CreateAIAgent("test-model", options); - - // Assert - Assert.NotNull(agent); - Assert.Equal("test-agent", agent.Name); - Assert.Equal("Test instructions", agent.Instructions); - } - - /// - /// Verify that CreateAIAgent with model and options and clientFactory applies the factory. - /// - [Fact] - public void CreateAIAgent_WithModelAndOptions_WithClientFactory_AppliesFactoryCorrectly() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", instructions: "Test instructions"); - var options = new ChatClientAgentOptions - { - Name = "test-agent", - ChatOptions = new() { Instructions = "Test instructions" } - }; - TestChatClient? testChatClient = null; - - // Act - var agent = client.CreateAIAgent( - "test-model", - options, - clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); - - // Assert - Assert.NotNull(agent); - var retrievedTestClient = agent.GetService(); - Assert.NotNull(retrievedTestClient); - Assert.Same(testChatClient, retrievedTestClient); - } - /// /// Verify that CreateAIAgentAsync with model and options creates a valid agent. /// @@ -889,7 +557,7 @@ public async Task CreateAIAgentAsync_WithAgentDefinition_WithNullDefinition_Thro /// Verify that CreateAIAgent creates an agent successfully. /// [Fact] - public void CreateAIAgent_WithDefinition_CreatesAgentSuccessfully() + public async Task CreateAIAgentAsync_WithDefinition_CreatesAgentSuccessfullyAsync() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); @@ -897,7 +565,7 @@ public void CreateAIAgent_WithDefinition_CreatesAgentSuccessfully() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); @@ -908,7 +576,7 @@ public void CreateAIAgent_WithDefinition_CreatesAgentSuccessfully() /// Verify that CreateAIAgent without tools parameter creates an agent successfully. /// [Fact] - public void CreateAIAgent_WithoutToolsParameter_CreatesAgentSuccessfully() + public async Task CreateAIAgentAsync_WithoutToolsParameter_CreatesAgentSuccessfullyAsync() { // Arrange var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; @@ -919,7 +587,7 @@ public void CreateAIAgent_WithoutToolsParameter_CreatesAgentSuccessfully() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); @@ -930,7 +598,7 @@ public void CreateAIAgent_WithoutToolsParameter_CreatesAgentSuccessfully() /// Verify that CreateAIAgent without tools in definition creates an agent successfully. /// [Fact] - public void CreateAIAgent_WithoutToolsInDefinition_CreatesAgentSuccessfully() + public async Task CreateAIAgentAsync_WithoutToolsInDefinition_CreatesAgentSuccessfullyAsync() { // Arrange var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; @@ -939,7 +607,7 @@ public void CreateAIAgent_WithoutToolsInDefinition_CreatesAgentSuccessfully() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); @@ -950,7 +618,7 @@ public void CreateAIAgent_WithoutToolsInDefinition_CreatesAgentSuccessfully() /// Verify that CreateAIAgent uses tools from the definition when no separate tools parameter is provided. /// [Fact] - public void CreateAIAgent_WithDefinitionTools_UsesDefinitionTools() + public async Task CreateAIAgentAsync_WithDefinitionTools_UsesDefinitionToolsAsync() { // Arrange var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; @@ -965,7 +633,7 @@ public void CreateAIAgent_WithDefinitionTools_UsesDefinitionTools() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); @@ -981,59 +649,55 @@ public void CreateAIAgent_WithDefinitionTools_UsesDefinitionTools() } /// - /// Verify that CreateAIAgentAsync when AI Tools are provided, uses them for the definition via http request. + /// Verify that CreateAIAgent creates an agent successfully when definition has a mix of custom and hosted tools. /// [Fact] - public async Task CreateAIAgentAsync_WithNameAndAITools_SendsToolDefinitionViaHttpAsync() + public async Task CreateAIAgentAsync_WithMixedToolsInDefinition_CreatesAgentSuccessfullyAsync() { // Arrange - using var httpHandler = new HttpHandlerAssert(async (request) => - { - if (request.Content is not null) - { - var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false); - - Assert.Contains("required_tool", requestBody); - } + var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; + definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false)); + definition.Tools.Add(new HostedWebSearchTool().GetService() ?? new HostedWebSearchTool().AsOpenAIResponseTool()); + definition.Tools.Add(new HostedFileSearchTool().GetService() ?? new HostedFileSearchTool().AsOpenAIResponseTool()); - return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentVersionResponseJson(), Encoding.UTF8, "application/json") }; - }); + // Simulate agent definition response with the tools + var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; + foreach (var tool in definition.Tools) + { + definitionResponse.Tools.Add(tool); + } -#pragma warning disable CA5399 - using var httpClient = new HttpClient(httpHandler); -#pragma warning restore CA5399 + AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse); - var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) }); + var options = new AgentVersionCreationOptions(definition); // Act - var agent = await client.CreateAIAgentAsync( - name: "test-agent", - model: "test-model", - instructions: "Test", - tools: [AIFunctionFactory.Create(() => true, "required_tool")]); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); Assert.IsType(agent); var agentVersion = agent.GetService(); Assert.NotNull(agentVersion); - Assert.IsType(agentVersion.Definition); + if (agentVersion.Definition is PromptAgentDefinition promptDef) + { + Assert.NotEmpty(promptDef.Tools); + Assert.Equal(3, promptDef.Tools.Count); + } } /// - /// Verify that CreateAIAgent when AI Tools are provided, uses them for the definition via http request. + /// Verify that CreateAIAgentAsync when AI Tools are provided, uses them for the definition via http request. /// [Fact] - public void CreateAIAgent_WithNameAndAITools_SendsToolDefinitionViaHttp() + public async Task CreateAIAgentAsync_WithNameAndAITools_SendsToolDefinitionViaHttpAsync() { // Arrange - using var httpHandler = new HttpHandlerAssert((request) => + using var httpHandler = new HttpHandlerAssert(async (request) => { if (request.Content is not null) { -#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits - var requestBody = request.Content.ReadAsStringAsync().GetAwaiter().GetResult(); -#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits + var requestBody = await request.Content.ReadAsStringAsync().ConfigureAwait(false); Assert.Contains("required_tool", requestBody); } @@ -1048,7 +712,7 @@ public void CreateAIAgent_WithNameAndAITools_SendsToolDefinitionViaHttp() var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) }); // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( name: "test-agent", model: "test-model", instructions: "Test", @@ -1063,32 +727,10 @@ public void CreateAIAgent_WithNameAndAITools_SendsToolDefinitionViaHttp() } /// - /// Verify that CreateAIAgent without tools creates an agent successfully. - /// - [Fact] - public void CreateAIAgent_WithoutTools_CreatesAgentSuccessfully() - { - // Arrange - var definition = new PromptAgentDefinition("test-model"); - - var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, null); - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse); - - var options = new AgentVersionCreationOptions(definition); - - // Act - var agent = client.CreateAIAgent("test-agent", options); - - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - } - - /// - /// Verify that when providing AITools with GetAIAgent, any additional tool that doesn't match the tools in agent definition are ignored. + /// Verify that when providing AITools with AsAIAgent, any additional tool that doesn't match the tools in agent definition are ignored. /// [Fact] - public void GetAIAgent_AdditionalAITools_WhenNotInTheDefinitionAreIgnored() + public void AsAIAgent_AdditionalAITools_WhenNotInTheDefinitionAreIgnored() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); @@ -1121,158 +763,37 @@ public void GetAIAgent_AdditionalAITools_WhenNotInTheDefinitionAreIgnored() #region Inline Tools vs Parameter Tools Tests /// - /// Verify that tools passed as parameters are accepted by GetAIAgent. + /// Verify that tools passed as parameters are accepted by AsAIAgent. /// - [Fact] - public void GetAIAgent_WithParameterTools_AcceptsTools() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - AgentRecord agentRecord = this.CreateTestAgentRecord(); - var tools = new List - { - AIFunctionFactory.Create(() => "tool1", "param_tool_1", "First parameter tool"), - AIFunctionFactory.Create(() => "tool2", "param_tool_2", "Second parameter tool") - }; - - // Act - var agent = client.AsAIAgent(agentRecord, tools: tools); - - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - var chatClient = agent.GetService(); - Assert.NotNull(chatClient); - var agentVersion = chatClient.GetService(); - Assert.NotNull(agentVersion); - } - - /// - /// Verify that CreateAIAgent with tools in definition creates an agent successfully. - /// - [Fact] - public void CreateAIAgent_WithDefinitionTools_CreatesAgentSuccessfully() - { - // Arrange - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; - definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false)); - - // Simulate agent definition response with the tools - var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList()); - - AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse); - - var options = new AgentVersionCreationOptions(definition); - - // Act - var agent = client.CreateAIAgent("test-agent", options); - - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - var agentVersion = agent.GetService(); - Assert.NotNull(agentVersion); - if (agentVersion.Definition is PromptAgentDefinition promptDef) - { - Assert.NotEmpty(promptDef.Tools); - Assert.Single(promptDef.Tools); - } - } - - /// - /// Verify that CreateAIAgent creates an agent successfully when definition has a mix of custom and hosted tools. - /// - [Fact] - public void CreateAIAgent_WithMixedToolsInDefinition_CreatesAgentSuccessfully() - { - // Arrange - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; - definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false)); - definition.Tools.Add(new HostedWebSearchTool().GetService() ?? new HostedWebSearchTool().AsOpenAIResponseTool()); - definition.Tools.Add(new HostedFileSearchTool().GetService() ?? new HostedFileSearchTool().AsOpenAIResponseTool()); - - // Simulate agent definition response with the tools - var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; - foreach (var tool in definition.Tools) - { - definitionResponse.Tools.Add(tool); - } - - AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse); - - var options = new AgentVersionCreationOptions(definition); - - // Act - var agent = client.CreateAIAgent("test-agent", options); - - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - var agentVersion = agent.GetService(); - Assert.NotNull(agentVersion); - if (agentVersion.Definition is PromptAgentDefinition promptDef) - { - Assert.NotEmpty(promptDef.Tools); - Assert.Equal(3, promptDef.Tools.Count); - } - } - - /// - /// Verifies that CreateAIAgent uses tools from definition when they are ResponseTool instances, resulting in successful agent creation. - /// - [Fact] - public void CreateAIAgent_WithResponseToolsInDefinition_CreatesAgentSuccessfully() - { - // Arrange - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; - - var fabricToolOptions = new FabricDataAgentToolOptions(); - fabricToolOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id")); - - var sharepointOptions = new SharePointGroundingToolOptions(); - sharepointOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id")); - - var structuredOutputs = new StructuredOutputDefinition("name", "description", BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()), false); - - // Add tools to the definition - definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false)); - definition.Tools.Add((ResponseTool)AgentTool.CreateBingCustomSearchTool(new BingCustomSearchToolParameters([new BingCustomSearchConfiguration("connection-id", "instance-name")]))); - definition.Tools.Add((ResponseTool)AgentTool.CreateBrowserAutomationTool(new BrowserAutomationToolParameters(new BrowserAutomationToolConnectionParameters("id")))); - definition.Tools.Add(AgentTool.CreateA2ATool(new Uri("https://test-uri.microsoft.com"))); - definition.Tools.Add((ResponseTool)AgentTool.CreateBingGroundingTool(new BingGroundingSearchToolOptions([new BingGroundingSearchConfiguration("connection-id")]))); - definition.Tools.Add((ResponseTool)AgentTool.CreateMicrosoftFabricTool(fabricToolOptions)); - definition.Tools.Add((ResponseTool)AgentTool.CreateOpenApiTool(new OpenAPIFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenAPIAnonymousAuthenticationDetails()))); - definition.Tools.Add((ResponseTool)AgentTool.CreateSharepointTool(sharepointOptions)); - definition.Tools.Add((ResponseTool)AgentTool.CreateStructuredOutputsTool(structuredOutputs)); - definition.Tools.Add((ResponseTool)AgentTool.CreateAzureAISearchTool(new AzureAISearchToolOptions([new AzureAISearchToolIndex() { IndexName = "name" }]))); - - // Generate agent definition response with the tools - var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList()); - - AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse); - - var options = new AgentVersionCreationOptions(definition); + [Fact] + public void AsAIAgent_WithParameterTools_AcceptsTools() + { + // Arrange + AIProjectClient client = this.CreateTestAgentClient(); + AgentRecord agentRecord = this.CreateTestAgentRecord(); + var tools = new List + { + AIFunctionFactory.Create(() => "tool1", "param_tool_1", "First parameter tool"), + AIFunctionFactory.Create(() => "tool2", "param_tool_2", "Second parameter tool") + }; // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = client.AsAIAgent(agentRecord, tools: tools); // Assert Assert.NotNull(agent); Assert.IsType(agent); - var agentVersion = agent.GetService(); + var chatClient = agent.GetService(); + Assert.NotNull(chatClient); + var agentVersion = chatClient.GetService(); Assert.NotNull(agentVersion); - if (agentVersion.Definition is PromptAgentDefinition promptDef) - { - Assert.NotEmpty(promptDef.Tools); - Assert.Equal(10, promptDef.Tools.Count); - } } /// /// Verify that CreateAIAgent with string parameters and tools creates an agent. /// [Fact] - public void CreateAIAgent_WithStringParamsAndTools_CreatesAgent() + public async Task CreateAIAgentAsync_WithStringParamsAndTools_CreatesAgentAsync() { // Arrange var tools = new List @@ -1285,7 +806,7 @@ public void CreateAIAgent_WithStringParamsAndTools_CreatesAgent() AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse); // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( "test-agent", "test-model", "Test instructions", @@ -1350,97 +871,54 @@ public async Task GetAIAgentAsync_WithToolsParameter_CreatesAgentAsync() #region Declarative Function Handling Tests /// - /// Verify that CreateAIAgent accepts declarative functions from definition. - /// - [Fact] - public void CreateAIAgent_WithDeclarativeFunctionInDefinition_AcceptsDeclarativeFunction() - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; - - // Create a declarative function (not invocable) using AIFunctionFactory.CreateDeclaration - using var doc = JsonDocument.Parse("{}"); - var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement); - - // Add to definition - definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException()); - - var options = new AgentVersionCreationOptions(definition); - - // Act - var agent = client.CreateAIAgent("test-agent", options); - - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - } - - /// - /// Verify that CreateAIAgent accepts declarative functions from definition. + /// Verifies that CreateAIAgent uses tools from definition when they are ResponseTool instances, resulting in successful agent creation. /// [Fact] - public void CreateAIAgent_WithDeclarativeFunctionFromDefinition_AcceptsDeclarativeFunction() + public async Task CreateAIAgentAsync_WithResponseToolsInDefinition_CreatesAgentSuccessfullyAsync() { // Arrange - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; - - // Create a declarative function (not invocable) using AIFunctionFactory.CreateDeclaration - using var doc = JsonDocument.Parse("{}"); - var declarativeFunction = AIFunctionFactory.CreateDeclaration("test_function", "A test function", doc.RootElement); - - // Add to definition - definition.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException()); - - // Generate response with the declarative function - var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" }; - definitionResponse.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException()); - - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse); - - var options = new AgentVersionCreationOptions(definition); + var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; - // Act - var agent = client.CreateAIAgent("test-agent", options); + var fabricToolOptions = new FabricDataAgentToolOptions(); + fabricToolOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id")); - // Assert - Assert.NotNull(agent); - Assert.IsType(agent); - } + var sharepointOptions = new SharePointGroundingToolOptions(); + sharepointOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id")); - /// - /// Verify that CreateAIAgent accepts FunctionTools from definition. - /// - [Fact] - public void CreateAIAgent_WithFunctionToolsInDefinition_AcceptsDeclarativeFunction() - { - // Arrange - var functionTool = ResponseTool.CreateFunctionTool( - functionName: "get_user_name", - functionParameters: BinaryData.FromString("{}"), - strictModeEnabled: false, - functionDescription: "Gets the user's name, as used for friendly address." - ); + var structuredOutputs = new StructuredOutputDefinition("name", "description", BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()), false); - var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; - definition.Tools.Add(functionTool); + // Add tools to the definition + definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false)); + definition.Tools.Add((ResponseTool)AgentTool.CreateBingCustomSearchTool(new BingCustomSearchToolParameters([new BingCustomSearchConfiguration("connection-id", "instance-name")]))); + definition.Tools.Add((ResponseTool)AgentTool.CreateBrowserAutomationTool(new BrowserAutomationToolParameters(new BrowserAutomationToolConnectionParameters("id")))); + definition.Tools.Add(AgentTool.CreateA2ATool(new Uri("https://test-uri.microsoft.com"))); + definition.Tools.Add((ResponseTool)AgentTool.CreateBingGroundingTool(new BingGroundingSearchToolOptions([new BingGroundingSearchConfiguration("connection-id")]))); + definition.Tools.Add((ResponseTool)AgentTool.CreateMicrosoftFabricTool(fabricToolOptions)); + definition.Tools.Add((ResponseTool)AgentTool.CreateOpenApiTool(new OpenAPIFunctionDefinition("name", BinaryData.FromString(OpenAPISpec), new OpenAPIAnonymousAuthenticationDetails()))); + definition.Tools.Add((ResponseTool)AgentTool.CreateSharepointTool(sharepointOptions)); + definition.Tools.Add((ResponseTool)AgentTool.CreateStructuredOutputsTool(structuredOutputs)); + definition.Tools.Add((ResponseTool)AgentTool.CreateAzureAISearchTool(new AzureAISearchToolOptions([new AzureAISearchToolIndex() { IndexName = "name" }]))); - // Generate response with the declarative function - var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" }; - definitionResponse.Tools.Add(functionTool); + // Generate agent definition response with the tools + var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList()); - AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse); + AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse); var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); Assert.IsType(agent); - var definitionFromAgent = Assert.IsType(agent.GetService()?.Definition); - Assert.Single(definitionFromAgent.Tools); + var agentVersion = agent.GetService(); + Assert.NotNull(agentVersion); + if (agentVersion.Definition is PromptAgentDefinition promptDef) + { + Assert.NotEmpty(promptDef.Tools); + Assert.Equal(10, promptDef.Tools.Count); + } } /// @@ -1543,7 +1021,7 @@ public async Task CreateAIAgentAsync_WithDeclarativeFunctionInDefinition_Accepts /// Verify that ChatClientAgentOptions are generated correctly without tools. /// [Fact] - public void CreateAIAgent_GeneratesCorrectChatClientAgentOptions() + public async Task CreateAIAgentAsync_GeneratesCorrectChatClientAgentOptionsAsync() { // Arrange var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }; @@ -1554,7 +1032,7 @@ public void CreateAIAgent_GeneratesCorrectChatClientAgentOptions() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent("test-agent", options); + var agent = await client.CreateAIAgentAsync("test-agent", options); // Assert Assert.NotNull(agent); @@ -1565,10 +1043,10 @@ public void CreateAIAgent_GeneratesCorrectChatClientAgentOptions() } /// - /// Verify that ChatClientAgentOptions preserve custom properties from input options. + /// Verify that GetAIAgentAsync with options preserves custom properties from input options. /// [Fact] - public void GetAIAgent_WithOptions_PreservesCustomProperties() + public async Task GetAIAgentAsync_WithOptions_PreservesCustomPropertiesAsync() { // Arrange AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", instructions: "Custom instructions", description: "Custom description"); @@ -1580,7 +1058,7 @@ public void GetAIAgent_WithOptions_PreservesCustomProperties() }; // Act - var agent = client.GetAIAgent(options); + var agent = await client.GetAIAgentAsync(options); // Assert Assert.NotNull(agent); @@ -1590,10 +1068,10 @@ public void GetAIAgent_WithOptions_PreservesCustomProperties() } /// - /// Verify that CreateAIAgent with options generates correct ChatClientAgentOptions with tools. + /// Verify that CreateAIAgentAsync with options and tools generates correct ChatClientAgentOptions. /// [Fact] - public void CreateAIAgent_WithOptionsAndTools_GeneratesCorrectOptions() + public async Task CreateAIAgentAsync_WithOptionsAndTools_GeneratesCorrectOptionsAsync() { // Arrange var tools = new List @@ -1614,7 +1092,7 @@ public void CreateAIAgent_WithOptionsAndTools_GeneratesCorrectOptions() }; // Act - var agent = client.CreateAIAgent("test-model", options); + var agent = await client.CreateAIAgentAsync("test-model", options); // Assert Assert.NotNull(agent); @@ -1636,14 +1114,14 @@ public void CreateAIAgent_WithOptionsAndTools_GeneratesCorrectOptions() /// [Theory] [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void GetAIAgent_ByName_WithInvalidAgentName_ThrowsArgumentException(string invalidName) + public void AsAIAgent_ByName_WithInvalidAgentName_ThrowsArgumentException(string invalidName) { // Arrange var mockClient = new Mock(); // Act & Assert var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent(invalidName)); + mockClient.Object.AsAIAgent(invalidName)); Assert.Equal("name", exception.ParamName); Assert.Contains("Agent name must be 1-63 characters long", exception.Message); @@ -1667,25 +1145,6 @@ public async Task GetAIAgentAsync_ByName_WithInvalidAgentName_ThrowsArgumentExce Assert.Contains("Agent name must be 1-63 characters long", exception.Message); } - /// - /// Verify that GetAIAgent with ChatClientAgentOptions throws ArgumentException when agent name is invalid. - /// - [Theory] - [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void GetAIAgent_WithOptions_WithInvalidAgentName_ThrowsArgumentException(string invalidName) - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - var options = new ChatClientAgentOptions { Name = invalidName }; - - // Act & Assert - var exception = Assert.Throws(() => - client.GetAIAgent(options)); - - Assert.Equal("name", exception.ParamName); - Assert.Contains("Agent name must be 1-63 characters long", exception.Message); - } - /// /// Verify that GetAIAgentAsync with ChatClientAgentOptions throws ArgumentException when agent name is invalid. /// @@ -1705,24 +1164,6 @@ public async Task GetAIAgentAsync_WithOptions_WithInvalidAgentName_ThrowsArgumen Assert.Contains("Agent name must be 1-63 characters long", exception.Message); } - /// - /// Verify that CreateAIAgent throws ArgumentException when agent name is invalid. - /// - [Theory] - [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void CreateAIAgent_WithBasicParams_WithInvalidAgentName_ThrowsArgumentException(string invalidName) - { - // Arrange - var mockClient = new Mock(); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent(invalidName, "model", "instructions")); - - Assert.Equal("name", exception.ParamName); - Assert.Contains("Agent name must be 1-63 characters long", exception.Message); - } - /// /// Verify that CreateAIAgentAsync throws ArgumentException when agent name is invalid. /// @@ -1741,26 +1182,6 @@ public async Task CreateAIAgentAsync_WithBasicParams_WithInvalidAgentName_Throws Assert.Contains("Agent name must be 1-63 characters long", exception.Message); } - /// - /// Verify that CreateAIAgent with AgentVersionCreationOptions throws ArgumentException when agent name is invalid. - /// - [Theory] - [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void CreateAIAgent_WithAgentDefinition_WithInvalidAgentName_ThrowsArgumentException(string invalidName) - { - // Arrange - var mockClient = new Mock(); - var definition = new PromptAgentDefinition("test-model"); - var options = new AgentVersionCreationOptions(definition); - - // Act & Assert - var exception = Assert.Throws(() => - mockClient.Object.CreateAIAgent(invalidName, options)); - - Assert.Equal("name", exception.ParamName); - Assert.Contains("Agent name must be 1-63 characters long", exception.Message); - } - /// /// Verify that CreateAIAgentAsync with AgentVersionCreationOptions throws ArgumentException when agent name is invalid. /// @@ -1781,25 +1202,6 @@ public async Task CreateAIAgentAsync_WithAgentDefinition_WithInvalidAgentName_Th Assert.Contains("Agent name must be 1-63 characters long", exception.Message); } - /// - /// Verify that CreateAIAgent with ChatClientAgentOptions throws ArgumentException when agent name is invalid. - /// - [Theory] - [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void CreateAIAgent_WithOptions_WithInvalidAgentName_ThrowsArgumentException(string invalidName) - { - // Arrange - AIProjectClient client = this.CreateTestAgentClient(); - var options = new ChatClientAgentOptions { Name = invalidName }; - - // Act & Assert - var exception = Assert.Throws(() => - client.CreateAIAgent("test-model", options)); - - Assert.Equal("name", exception.ParamName); - Assert.Contains("Agent name must be 1-63 characters long", exception.Message); - } - /// /// Verify that CreateAIAgentAsync with ChatClientAgentOptions throws ArgumentException when agent name is invalid. /// @@ -1820,11 +1222,11 @@ public async Task CreateAIAgentAsync_WithOptions_WithInvalidAgentName_ThrowsArgu } /// - /// Verify that GetAIAgent with AgentReference throws ArgumentException when agent name is invalid. + /// Verify that AsAIAgent with AgentReference throws ArgumentException when agent name is invalid. /// [Theory] [MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))] - public void GetAIAgent_WithAgentReference_WithInvalidAgentName_ThrowsArgumentException(string invalidName) + public void AsAIAgent_WithAgentReference_WithInvalidAgentName_ThrowsArgumentException(string invalidName) { // Arrange var mockClient = new Mock(); @@ -1832,7 +1234,7 @@ public void GetAIAgent_WithAgentReference_WithInvalidAgentName_ThrowsArgumentExc // Act & Assert var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent(agentReference)); + mockClient.Object.AsAIAgent(agentReference)); Assert.Equal("name", exception.ParamName); Assert.Contains("Agent name must be 1-63 characters long", exception.Message); @@ -1873,7 +1275,7 @@ public void AsAIAgent_WithClientFactory_WrapsUnderlyingChatClient() /// Verify that clientFactory is called with the correct underlying chat client. /// [Fact] - public void CreateAIAgent_WithClientFactory_ReceivesCorrectUnderlyingClient() + public async Task CreateAIAgentAsync_WithClientFactory_ReceivesCorrectUnderlyingClientAsync() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); @@ -1883,7 +1285,7 @@ public void CreateAIAgent_WithClientFactory_ReceivesCorrectUnderlyingClient() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( "test-agent", options, clientFactory: (innerClient) => @@ -1932,7 +1334,7 @@ public void AsAIAgent_MultipleCallsWithClientFactory_CreatesIndependentClients() /// Verify that agent created with clientFactory maintains agent properties. /// [Fact] - public void CreateAIAgent_WithClientFactory_PreservesAgentProperties() + public async Task CreateAIAgentAsync_WithClientFactory_PreservesAgentPropertiesAsync() { // Arrange const string AgentName = "test-agent"; @@ -1941,7 +1343,7 @@ public void CreateAIAgent_WithClientFactory_PreservesAgentProperties() AIProjectClient client = this.CreateTestAgentClient(AgentName, Instructions); // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( AgentName, Model, Instructions, @@ -1959,7 +1361,7 @@ public void CreateAIAgent_WithClientFactory_PreservesAgentProperties() /// Verify that agent created with clientFactory is created successfully. /// [Fact] - public void CreateAIAgent_WithClientFactory_CreatesAgentSuccessfully() + public async Task CreateAIAgentAsync_WithClientFactory_CreatesAgentSuccessfullyAsync() { // Arrange var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" }; @@ -1970,7 +1372,7 @@ public void CreateAIAgent_WithClientFactory_CreatesAgentSuccessfully() var options = new AgentVersionCreationOptions(definition); // Act - var agent = client.CreateAIAgent( + var agent = await client.CreateAIAgentAsync( "test-agent", options, clientFactory: (innerClient) => new TestChatClient(innerClient)); @@ -1987,122 +1389,11 @@ public void CreateAIAgent_WithClientFactory_CreatesAgentSuccessfully() #region User-Agent Header Tests - /// - /// Verify that GetAIAgent(string name) passes RequestOptions to the Protocol method. - /// - [Fact] - public void GetAIAgent_WithStringName_PassesRequestOptionsToProtocol() - { - // Arrange - RequestOptions? capturedRequestOptions = null; - - var mockAgentOperations = new Mock(); - mockAgentOperations - .Setup(x => x.GetAgent(It.IsAny(), It.IsAny())) - .Callback((name, options) => capturedRequestOptions = options) - .Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentResponseJson())))); - - var mockAgentClient = new Mock(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider()); - mockAgentClient.SetupGet(x => x.Agents).Returns(mockAgentOperations.Object); - mockAgentClient.Setup(x => x.GetConnection(It.IsAny())).Returns(new ClientConnection("fake-connection-id", "http://localhost", ClientPipeline.Create(), CredentialKind.None)); - - // Act - var agent = mockAgentClient.Object.GetAIAgent("test-agent"); - - // Assert - Assert.NotNull(agent); - Assert.NotNull(capturedRequestOptions); - } - - /// - /// Verify that GetAIAgentAsync(string name) passes RequestOptions to the Protocol method. - /// - [Fact] - public async Task GetAIAgentAsync_WithStringName_PassesRequestOptionsToProtocolAsync() - { - // Arrange - RequestOptions? capturedRequestOptions = null; - - var mockAgentOperations = new Mock(); - mockAgentOperations - .Setup(x => x.GetAgentAsync(It.IsAny(), It.IsAny())) - .Callback((name, options) => capturedRequestOptions = options) - .Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentResponseJson()))))); - - var mockAgentClient = new Mock(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider()); - mockAgentClient.SetupGet(x => x.Agents).Returns(mockAgentOperations.Object); - mockAgentClient.Setup(x => x.GetConnection(It.IsAny())).Returns(new ClientConnection("fake-connection-id", "http://localhost", ClientPipeline.Create(), CredentialKind.None)); - // Act - var agent = await mockAgentClient.Object.GetAIAgentAsync("test-agent"); - - // Assert - Assert.NotNull(agent); - Assert.NotNull(capturedRequestOptions); - } - - /// - /// Verify that CreateAIAgent(string model, ChatClientAgentOptions options) passes RequestOptions to the Protocol method. - /// - [Fact] - public void CreateAIAgent_WithChatClientAgentOptions_PassesRequestOptionsToProtocol() - { - // Arrange - RequestOptions? capturedRequestOptions = null; - - var mockAgentOperations = new Mock(); - mockAgentOperations - .Setup(x => x.CreateAgentVersion(It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((name, content, options) => capturedRequestOptions = options) - .Returns(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentVersionResponseJson())))); - - var mockAgentClient = new Mock(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider()); - mockAgentClient.SetupGet(x => x.Agents).Returns(mockAgentOperations.Object); - mockAgentClient.Setup(x => x.GetConnection(It.IsAny())).Returns(new ClientConnection("fake-connection-id", "http://localhost", ClientPipeline.Create(), CredentialKind.None)); - - var agentOptions = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act - var agent = mockAgentClient.Object.CreateAIAgent("gpt-4", agentOptions); - - // Assert - Assert.NotNull(agent); - Assert.NotNull(capturedRequestOptions); - } - - /// - /// Verify that CreateAIAgentAsync(string model, ChatClientAgentOptions options) passes RequestOptions to the Protocol method. - /// - [Fact] - public async Task CreateAIAgentAsync_WithChatClientAgentOptions_PassesRequestOptionsToProtocolAsync() - { - // Arrange - RequestOptions? capturedRequestOptions = null; - - var mockAgentOperations = new Mock(); - mockAgentOperations - .Setup(x => x.CreateAgentVersionAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((name, content, options) => capturedRequestOptions = options) - .Returns(Task.FromResult(ClientResult.FromResponse(new MockPipelineResponse(200, BinaryData.FromString(TestDataUtil.GetAgentVersionResponseJson()))))); - - var mockAgentClient = new Mock(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider()); - mockAgentClient.SetupGet(x => x.Agents).Returns(mockAgentOperations.Object); - mockAgentClient.Setup(x => x.GetConnection(It.IsAny())).Returns(new ClientConnection("fake-connection-id", "http://localhost", ClientPipeline.Create(), CredentialKind.None)); - - var agentOptions = new ChatClientAgentOptions { Name = "test-agent" }; - - // Act - var agent = await mockAgentClient.Object.CreateAIAgentAsync("gpt-4", agentOptions); - - // Assert - Assert.NotNull(agent); - Assert.NotNull(capturedRequestOptions); - } - /// /// Verifies that the user-agent header is added to both synchronous and asynchronous requests made by agent creation methods. /// [Fact] - public async Task CreateAIAgent_UserAgentHeaderAddedToRequestsAsync() + public async Task CreateAIAgentAsync_UserAgentHeaderAddedToRequestsAsync() { using var httpHandler = new HttpHandlerAssert(request => { @@ -2122,16 +1413,14 @@ public async Task CreateAIAgent_UserAgentHeaderAddedToRequestsAsync() var agentOptions = new ChatClientAgentOptions { Name = "test-agent" }; // Act - var agent1 = aiProjectClient.CreateAIAgent("test", agentOptions); - var agent2 = await aiProjectClient.CreateAIAgentAsync("test", agentOptions); + var agent = await aiProjectClient.CreateAIAgentAsync("test", agentOptions); // Assert - Assert.NotNull(agent1); - Assert.NotNull(agent2); + Assert.NotNull(agent); } /// - /// Verifies that the user-agent header is added to both synchronous and asynchronous GetAIAgent requests. + /// Verifies that the user-agent header is added to asynchronous GetAIAgentAsync requests. /// [Fact] public async Task GetAIAgent_UserAgentHeaderAddedToRequestsAsync() @@ -2152,12 +1441,10 @@ public async Task GetAIAgent_UserAgentHeaderAddedToRequestsAsync() var aiProjectClient = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) }); // Act - var agent1 = aiProjectClient.GetAIAgent("test"); - var agent2 = await aiProjectClient.GetAIAgentAsync("test"); + var agent = await aiProjectClient.GetAIAgentAsync("test"); // Assert - Assert.NotNull(agent1); - Assert.NotNull(agent2); + Assert.NotNull(agent); } #endregion @@ -2168,7 +1455,7 @@ public async Task GetAIAgent_UserAgentHeaderAddedToRequestsAsync() /// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null. /// [Fact] - public void GetAIAgent_WithAgentReference_WithNullClient_ThrowsArgumentNullException() + public void AsAIAgent_WithAgentReference_WithNullClient_ThrowsArgumentNullException() { // Arrange AIProjectClient? client = null; @@ -2176,7 +1463,7 @@ public void GetAIAgent_WithAgentReference_WithNullClient_ThrowsArgumentNullExcep // Act & Assert var exception = Assert.Throws(() => - client!.GetAIAgent(agentReference)); + client!.AsAIAgent(agentReference)); Assert.Equal("aiProjectClient", exception.ParamName); } @@ -2185,30 +1472,30 @@ public void GetAIAgent_WithAgentReference_WithNullClient_ThrowsArgumentNullExcep /// Verify that AsAIAgent throws ArgumentNullException when agentReference is null. /// [Fact] - public void GetAIAgent_WithAgentReference_WithNullAgentReference_ThrowsArgumentNullException() + public void AsAIAgent_WithAgentReference_WithNullAgentReference_ThrowsArgumentNullException() { // Arrange var mockClient = new Mock(); // Act & Assert var exception = Assert.Throws(() => - mockClient.Object.GetAIAgent((AgentReference)null!)); + mockClient.Object.AsAIAgent((AgentReference)null!)); Assert.Equal("agentReference", exception.ParamName); } /// - /// Verify that GetAIAgent with AgentReference creates a valid agent. + /// Verify that AsAIAgent with AgentReference creates a valid agent. /// [Fact] - public void GetAIAgent_WithAgentReference_CreatesValidAgent() + public void AsAIAgent_WithAgentReference_CreatesValidAgent() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); var agentReference = new AgentReference("test-name", "1"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); // Assert Assert.NotNull(agent); @@ -2217,10 +1504,10 @@ public void GetAIAgent_WithAgentReference_CreatesValidAgent() } /// - /// Verify that GetAIAgent with AgentReference and clientFactory applies the factory. + /// Verify that AsAIAgent with AgentReference and clientFactory applies the factory. /// [Fact] - public void GetAIAgent_WithAgentReference_WithClientFactory_AppliesFactoryCorrectly() + public void AsAIAgent_WithAgentReference_WithClientFactory_AppliesFactoryCorrectly() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); @@ -2228,7 +1515,7 @@ public void GetAIAgent_WithAgentReference_WithClientFactory_AppliesFactoryCorrec TestChatClient? testChatClient = null; // Act - var agent = client.GetAIAgent( + var agent = client.AsAIAgent( agentReference, clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient)); @@ -2240,17 +1527,17 @@ public void GetAIAgent_WithAgentReference_WithClientFactory_AppliesFactoryCorrec } /// - /// Verify that GetAIAgent with AgentReference sets the agent ID correctly. + /// Verify that AsAIAgent with AgentReference sets the agent ID correctly. /// [Fact] - public void GetAIAgent_WithAgentReference_SetsAgentIdCorrectly() + public void AsAIAgent_WithAgentReference_SetsAgentIdCorrectly() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); var agentReference = new AgentReference("test-name", "2"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); // Assert Assert.NotNull(agent); @@ -2258,10 +1545,10 @@ public void GetAIAgent_WithAgentReference_SetsAgentIdCorrectly() } /// - /// Verify that GetAIAgent with AgentReference and tools includes the tools in ChatOptions. + /// Verify that AsAIAgent with AgentReference and tools includes the tools in ChatOptions. /// [Fact] - public void GetAIAgent_WithAgentReference_WithTools_IncludesToolsInChatOptions() + public void AsAIAgent_WithAgentReference_WithTools_IncludesToolsInChatOptions() { // Arrange AIProjectClient client = this.CreateTestAgentClient(); @@ -2272,7 +1559,7 @@ public void GetAIAgent_WithAgentReference_WithTools_IncludesToolsInChatOptions() }; // Act - var agent = client.GetAIAgent(agentReference, tools: tools); + var agent = client.AsAIAgent(agentReference, tools: tools); // Assert Assert.NotNull(agent); @@ -2316,7 +1603,7 @@ public void GetService_WithAgentReference_ReturnsNullForAgentRecord() var agentReference = new AgentReference("test-name", "1"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); var retrievedRecord = agent.GetService(); // Assert @@ -2357,7 +1644,7 @@ public void GetService_WithAgentReference_ReturnsNullForAgentVersion() var agentReference = new AgentReference("test-name", "1"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); var retrievedVersion = agent.GetService(); // Assert @@ -2447,7 +1734,7 @@ public void GetService_WithAgentReference_ReturnsAgentReference() var agentReference = new AgentReference("test-agent", "1.0"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); var retrievedReference = agent.GetService(); // Assert @@ -2505,7 +1792,7 @@ public void GetService_WithAgentReference_ReturnsCorrectVersionInformation() var agentReference = new AgentReference("versioned-agent", "3.5"); // Act - var agent = client.GetAIAgent(agentReference); + var agent = client.AsAIAgent(agentReference); var retrievedReference = agent.GetService(); // Assert diff --git a/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Extensions/OpenAIAssistantClientExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Extensions/OpenAIAssistantClientExtensionsTests.cs index 8400adfbcc..2401790dd0 100644 --- a/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Extensions/OpenAIAssistantClientExtensionsTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Extensions/OpenAIAssistantClientExtensionsTests.cs @@ -23,7 +23,7 @@ public sealed class OpenAIAssistantClientExtensionsTests /// Verify that CreateAIAgent with clientFactory parameter correctly applies the factory. /// [Fact] - public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly() + public async Task CreateAIAgentAsync_WithClientFactory_AppliesFactoryCorrectlyAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -31,7 +31,7 @@ public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly() const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", name: "Test Agent", @@ -53,7 +53,7 @@ public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly() /// Verify that CreateAIAgent with clientFactory using AsBuilder pattern works correctly. /// [Fact] - public void CreateAIAgent_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectly() + public async Task CreateAIAgentAsync_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectlyAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -62,7 +62,7 @@ public void CreateAIAgent_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectl const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", clientFactory: (innerClient) => @@ -83,7 +83,7 @@ public void CreateAIAgent_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectl /// Verify that CreateAIAgent with options and clientFactory parameter correctly applies the factory. /// [Fact] - public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly() + public async Task CreateAIAgentAsync_WithOptionsAndClientFactory_AppliesFactoryCorrectlyAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -97,7 +97,7 @@ public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly() }; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, options, clientFactory: (innerClient) => testChatClient); @@ -117,14 +117,14 @@ public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly() /// Verify that CreateAIAgent without clientFactory works normally. /// [Fact] - public void CreateAIAgent_WithoutClientFactory_WorksNormally() + public async Task CreateAIAgentAsync_WithoutClientFactory_WorksNormallyAsync() { // Arrange var assistantClient = new TestAssistantClient(); const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", name: "Test Agent"); @@ -142,14 +142,14 @@ public void CreateAIAgent_WithoutClientFactory_WorksNormally() /// Verify that CreateAIAgent with null clientFactory works normally. /// [Fact] - public void CreateAIAgent_WithNullClientFactory_WorksNormally() + public async Task CreateAIAgentAsync_WithNullClientFactory_WorksNormallyAsync() { // Arrange var assistantClient = new TestAssistantClient(); const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", name: "Test Agent", @@ -168,11 +168,11 @@ public void CreateAIAgent_WithNullClientFactory_WorksNormally() /// Verify that CreateAIAgent throws ArgumentNullException when client is null. /// [Fact] - public void CreateAIAgent_WithNullClient_ThrowsArgumentNullException() + public async Task CreateAIAgentAsync_WithNullClient_ThrowsArgumentNullExceptionAsync() { // Act & Assert - var exception = Assert.Throws(() => - ((AssistantClient)null!).CreateAIAgent("test-model")); + var exception = await Assert.ThrowsAsync(() => + ((AssistantClient)null!).CreateAIAgentAsync("test-model")); Assert.Equal("client", exception.ParamName); } @@ -181,14 +181,14 @@ public void CreateAIAgent_WithNullClient_ThrowsArgumentNullException() /// Verify that CreateAIAgent throws ArgumentNullException when model is null. /// [Fact] - public void CreateAIAgent_WithNullModel_ThrowsArgumentNullException() + public async Task CreateAIAgentAsync_WithNullModel_ThrowsArgumentNullExceptionAsync() { // Arrange var assistantClient = new TestAssistantClient(); // Act & Assert - var exception = Assert.Throws(() => - assistantClient.CreateAIAgent(null!)); + var exception = await Assert.ThrowsAsync(() => + assistantClient.CreateAIAgentAsync(null!)); Assert.Equal("model", exception.ParamName); } @@ -197,14 +197,14 @@ public void CreateAIAgent_WithNullModel_ThrowsArgumentNullException() /// Verify that CreateAIAgent with options throws ArgumentNullException when options is null. /// [Fact] - public void CreateAIAgent_WithNullOptions_ThrowsArgumentNullException() + public async Task CreateAIAgentAsync_WithNullOptions_ThrowsArgumentNullExceptionAsync() { // Arrange var assistantClient = new TestAssistantClient(); // Act & Assert - var exception = Assert.Throws(() => - assistantClient.CreateAIAgent("test-model", (ChatClientAgentOptions)null!)); + var exception = await Assert.ThrowsAsync(() => + assistantClient.CreateAIAgentAsync("test-model", (ChatClientAgentOptions)null!)); Assert.Equal("options", exception.ParamName); } @@ -286,33 +286,6 @@ public void AsAIAgent_WithAssistantAndOptionsWithNullFields_FallsBackToAssistant Assert.Equal("Original Instructions", agent.Instructions); } - /// - /// Verify that GetAIAgent with agentId and options works correctly. - /// - [Fact] - public void GetAIAgent_WithAgentIdAndOptions_WorksCorrectly() - { - // Arrange - var assistantClient = new TestAssistantClient(); - const string AgentId = "asst_abc123"; - - var options = new ChatClientAgentOptions - { - Name = "Override Name", - Description = "Override Description", - ChatOptions = new() { Instructions = "Override Instructions" } - }; - - // Act - var agent = assistantClient.GetAIAgent(AgentId, options); - - // Assert - Assert.NotNull(agent); - Assert.Equal("Override Name", agent.Name); - Assert.Equal("Override Description", agent.Description); - Assert.Equal("Override Instructions", agent.Instructions); - } - /// /// Verify that GetAIAgentAsync with agentId and options works correctly. /// @@ -423,23 +396,6 @@ public void AsAIAgent_WithNullOptions_ThrowsArgumentNullException() Assert.Equal("options", exception.ParamName); } - /// - /// Verify that GetAIAgent throws ArgumentException when agentId is empty. - /// - [Fact] - public void GetAIAgent_WithEmptyAgentId_ThrowsArgumentException() - { - // Arrange - var assistantClient = new TestAssistantClient(); - var options = new ChatClientAgentOptions(); - - // Act & Assert - var exception = Assert.Throws(() => - assistantClient.GetAIAgent(string.Empty, options)); - - Assert.Equal("agentId", exception.ParamName); - } - /// /// Verify that GetAIAgentAsync throws ArgumentException when agentId is empty. /// @@ -461,7 +417,7 @@ public async Task GetAIAgentAsync_WithEmptyAgentId_ThrowsArgumentExceptionAsync( /// Verify that CreateAIAgent with services parameter correctly passes it through to the ChatClientAgent. /// [Fact] - public void CreateAIAgent_WithServices_PassesServicesToAgent() + public async Task CreateAIAgentAsync_WithServices_PassesServicesToAgentAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -469,7 +425,7 @@ public void CreateAIAgent_WithServices_PassesServicesToAgent() const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", name: "Test Agent", @@ -490,7 +446,7 @@ public void CreateAIAgent_WithServices_PassesServicesToAgent() /// Verify that CreateAIAgent with options and services parameter correctly passes it through to the ChatClientAgent. /// [Fact] - public void CreateAIAgent_WithOptionsAndServices_PassesServicesToAgent() + public async Task CreateAIAgentAsync_WithOptionsAndServices_PassesServicesToAgentAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -503,7 +459,7 @@ public void CreateAIAgent_WithOptionsAndServices_PassesServicesToAgent() }; // Act - var agent = assistantClient.CreateAIAgent(ModelId, options, services: serviceProvider); + var agent = await assistantClient.CreateAIAgentAsync(ModelId, options, services: serviceProvider); // Assert Assert.NotNull(agent); @@ -570,7 +526,7 @@ public async Task GetAIAgentAsync_WithServices_PassesServicesToAgentAsync() /// Verify that CreateAIAgent with both clientFactory and services works correctly. /// [Fact] - public void CreateAIAgent_WithClientFactoryAndServices_AppliesBothCorrectly() + public async Task CreateAIAgentAsync_WithClientFactoryAndServices_AppliesBothCorrectlyAsync() { // Arrange var assistantClient = new TestAssistantClient(); @@ -579,7 +535,7 @@ public void CreateAIAgent_WithClientFactoryAndServices_AppliesBothCorrectly() const string ModelId = "test-model"; // Act - var agent = assistantClient.CreateAIAgent( + var agent = await assistantClient.CreateAIAgentAsync( ModelId, instructions: "Test instructions", name: "Test Agent", @@ -622,14 +578,9 @@ public TestAssistantClient() { } - public override ClientResult CreateAssistant(string model, AssistantCreationOptions? options = null, CancellationToken cancellationToken = default) + public override Task> CreateAssistantAsync(string model, AssistantCreationOptions? options = null, CancellationToken cancellationToken = default) { - return ClientResult.FromValue(ModelReaderWriter.Read(BinaryData.FromString("""{"id": "asst_abc123"}""")), new FakePipelineResponse())!; - } - - public override ClientResult GetAssistant(string assistantId, CancellationToken cancellationToken = default) - { - return ClientResult.FromValue(ModelReaderWriter.Read(BinaryData.FromString("""{"id": "asst_abc123", "name": "Original Name", "description": "Original Description", "instructions": "Original Instructions"}""")), new FakePipelineResponse())!; + return Task.FromResult>(ClientResult.FromValue(ModelReaderWriter.Read(BinaryData.FromString("""{"id": "asst_abc123"}""")), new FakePipelineResponse())!); } public override async Task> GetAssistantAsync(string assistantId, CancellationToken cancellationToken = default) diff --git a/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs b/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs index 0c8d6b80dd..02f5f36a76 100644 --- a/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs +++ b/dotnet/tests/OpenAIAssistant.IntegrationTests/OpenAIAssistantClientExtensionsTests.cs @@ -48,7 +48,7 @@ public async Task CreateAIAgentAsync_WithAIFunctionTool_InvokesFunctionAsync(str Tools = [weatherFunction] } }), - "CreateWithChatClientAgentOptionsSync" => this._assistantClient.CreateAIAgent( + "CreateWithChatClientAgentOptionsSync" => await this._assistantClient.CreateAIAgentAsync( model: s_config.ChatModelId!, options: new ChatClientAgentOptions() { @@ -115,7 +115,7 @@ public async Task CreateAIAgentAsync_WithHostedCodeInterpreter_RunsCodeAsync(str Tools = [codeInterpreterTool] } }), - "CreateWithChatClientAgentOptionsSync" => this._assistantClient.CreateAIAgent( + "CreateWithChatClientAgentOptionsSync" => await this._assistantClient.CreateAIAgentAsync( model: s_config.ChatModelId!, options: new ChatClientAgentOptions() { @@ -193,7 +193,7 @@ You are a helpful agent that can help fetch data from files you know about. Tools = [fileSearchTool] } }), - "CreateWithChatClientAgentOptionsSync" => this._assistantClient.CreateAIAgent( + "CreateWithChatClientAgentOptionsSync" => await this._assistantClient.CreateAIAgentAsync( model: s_config.ChatModelId!, options: new ChatClientAgentOptions() {