From d69d74cac6d51c1f9283d607f6d0640df0f42c2d Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 16:10:09 -0700 Subject: [PATCH 01/20] Updated --- dotnet/Directory.Packages.props | 3 +- dotnet/nuget.config | 7 +- .../AzureAIAgent/Step01_AzureAIAgent.cs | 9 +- .../Step02_AzureAIAgent_Plugins.cs | 13 +- .../AzureAIAgent/Step03_AzureAIAgent_Chat.cs | 10 +- .../Step04_AzureAIAgent_CodeInterpreter.cs | 11 +- .../Step05_AzureAIAgent_FileSearch.cs | 18 +-- .../Step06_AzureAIAgent_OpenAPI.cs | 10 +- .../Step07_AzureAIAgent_Functions.cs | 9 +- .../Step08_AzureAIAgent_Declarative.cs | 5 +- .../Step07_Assistant_Declarative.cs | 4 +- .../Step10_MultiAgent_Declarative.cs | 16 +-- .../src/Agents/AzureAI/Agents.AzureAI.csproj | 3 +- .../AzureAI/AzureAIAgent.ClientFactory.cs | 41 ++++-- dotnet/src/Agents/AzureAI/AzureAIAgent.cs | 13 +- .../src/Agents/AzureAI/AzureAIAgentThread.cs | 7 +- dotnet/src/Agents/AzureAI/AzureAIChannel.cs | 4 +- .../Agents/AzureAI/AzureAIClientProvider.cs | 19 +-- .../AzureAI/AzureAIThreadMessageFactory.cs | 2 +- .../AzureAI/Definition/AzureAIAgentFactory.cs | 7 +- .../Extensions/AgentDefinitionExtensions.cs | 27 ++-- .../AzureAI/Extensions/AgentRunExtensions.cs | 21 ++-- .../AgentToolDefinitionExtensions.cs | 2 +- .../Extensions/KernelFunctionExtensions.cs | 2 +- .../AzureAI/Internal/AgentMessageFactory.cs | 6 +- .../AzureAI/Internal/AgentThreadActions.cs | 21 ++-- .../Logging/AgentThreadActionsLogMessages.cs | 2 +- .../Extensions/AgentDefinitionExtensions.cs | 8 +- .../src/Agents/OpenAI/OpenAIClientProvider.cs | 1 + .../AzureAI/AzureAIClientProviderTests.cs | 8 +- .../Definition/AzureAIAgentFactoryTests.cs | 15 ++- .../KernelFunctionExtensionsTests.cs | 2 +- .../Internal/AgentMessageFactoryTests.cs | 2 +- .../OpenAIAssistantAgentFactoryTests.cs | 3 +- .../AssistantClientExtensionsTests.cs | 33 ++--- .../Extensions/OpenAIClientExtensionsTests.cs | 15 +-- .../OpenAI/OpenAIAssistantAgentTests.cs | 16 +-- .../OpenAI/OpenAIAssistantAgentThreadTests.cs | 25 ++-- .../Agents/UnitTests/Yaml/AgentYamlTests.cs | 20 +-- .../Yaml/AzureAIKernelAgentYamlTests.cs | 14 ++- .../Agents/MixedAgentTests.cs | 14 ++- .../Agents/OpenAIAssistantAgentTests.cs | 118 ++++++++++-------- .../samples/AgentUtilities/BaseAgentsTest.cs | 2 +- .../AgentUtilities/BaseAzureAgentTest.cs | 26 +--- .../samples/AgentUtilities/BaseAzureTest.cs | 18 +-- .../InternalUtilities/TestConfiguration.cs | 3 +- 46 files changed, 332 insertions(+), 303 deletions(-) diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props index aaf525b2f440..57297256731a 100644 --- a/dotnet/Directory.Packages.props +++ b/dotnet/Directory.Packages.props @@ -15,10 +15,11 @@ + - + diff --git a/dotnet/nuget.config b/dotnet/nuget.config index 7159fcd04c36..f3be7a2f9194 100644 --- a/dotnet/nuget.config +++ b/dotnet/nuget.config @@ -1,12 +1,17 @@ - + + + + + + diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs index 8db5be7a7984..6b8ccc83c9c6 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs @@ -1,4 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; @@ -19,10 +20,10 @@ public async Task UseTemplateForAzureAgent() string generateStoryYaml = EmbeddedResource.Read("GenerateStory.yaml"); PromptTemplateConfig templateConfig = KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml); // Instructions, Name and Description properties defined via the PromptTemplateConfig. - Azure.AI.Projects.Agent definition = await this.AgentsClient.CreateAgentAsync(TestConfiguration.AzureAI.ChatModelId, templateConfig.Name, templateConfig.Description, templateConfig.Template); + PersistentAgent definition = await this.Client.CreateAgentAsync(TestConfiguration.AzureAI.ChatModelId, templateConfig.Name, templateConfig.Description, templateConfig.Template); AzureAIAgent agent = new( definition, - this.AgentsClient, + this.Client, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { @@ -34,7 +35,7 @@ public async Task UseTemplateForAzureAgent() }; // Create a thread for the agent conversation. - AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); try { @@ -52,7 +53,7 @@ await InvokeAgentAsync( finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the response. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs index 908948650425..629f0ae5f15f 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs @@ -1,4 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; @@ -23,7 +24,7 @@ public async Task UseAzureAgentWithPlugin() name: "Host"); // Create a thread for the agent conversation. - AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -36,7 +37,7 @@ public async Task UseAzureAgentWithPlugin() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } } @@ -47,7 +48,7 @@ public async Task UseAzureAgentWithPluginEnumParameter() AzureAIAgent agent = await CreateAzureAgentAsync(plugin: KernelPluginFactory.CreateFromType()); // Create a thread for the agent conversation. - AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -57,20 +58,20 @@ public async Task UseAzureAgentWithPluginEnumParameter() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } } private async Task CreateAzureAgentAsync(KernelPlugin plugin, string? instructions = null, string? name = null) { // Define the agent - Azure.AI.Projects.Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, name, null, instructions); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Add to the agent's Kernel if (plugin != null) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs index c54d9cf78829..e59e5b14378e 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.Agents.Chat; using Microsoft.SemanticKernel.ChatCompletion; -using Agent = Azure.AI.Projects.Agent; namespace GettingStarted.AzureAgents; @@ -39,18 +39,18 @@ Consider suggestions when refining an idea. public async Task UseGroupChatWithTwoAgents() { // Define the agents - Agent reviewerModel = await this.AgentsClient.CreateAgentAsync( + PersistentAgent reviewerModel = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, ReviewerName, null, ReviewerInstructions); - AzureAIAgent agentReviewer = new(reviewerModel, this.AgentsClient); - Agent writerModel = await this.AgentsClient.CreateAgentAsync( + AzureAIAgent agentReviewer = new(reviewerModel, this.Client); + PersistentAgent writerModel = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, CopyWriterName, null, CopyWriterInstructions); - AzureAIAgent agentWriter = new(writerModel, this.AgentsClient); + AzureAIAgent agentWriter = new(writerModel, this.Client); // Create a chat for agent interaction. AgentGroupChat chat = diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs index 4c36e882d949..c396a0e9b984 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs @@ -1,4 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; @@ -15,13 +16,13 @@ public class Step04_AzureAIAgent_CodeInterpreter(ITestOutputHelper output) : Bas public async Task UseCodeInterpreterToolWithAgent() { // Define the agent - Azure.AI.Projects.Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, - tools: [new Azure.AI.Projects.CodeInterpreterToolDefinition()]); - AzureAIAgent agent = new(definition, this.AgentsClient); + tools: [new CodeInterpreterToolDefinition()]); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -31,7 +32,7 @@ public async Task UseCodeInterpreterToolWithAgent() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs index 1716c48d1b6f..a1a31d7b8f41 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; @@ -18,12 +18,12 @@ public async Task UseFileSearchToolWithAgent() // Define the agent await using Stream stream = EmbeddedResource.ReadStream("employees.pdf")!; - AgentFile fileInfo = await this.AgentsClient.UploadFileAsync(stream, AgentFilePurpose.Agents, "employees.pdf"); + PersistentAgentFile fileInfo = await this.Client.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "employees.pdf"); VectorStore fileStore = - await this.AgentsClient.CreateVectorStoreAsync( + await this.Client.CreateVectorStoreAsync( [fileInfo.Id], metadata: new Dictionary() { { SampleMetadataKey, bool.TrueString } }); - Agent agentModel = await this.AgentsClient.CreateAgentAsync( + PersistentAgent agentModel = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new FileSearchToolDefinition()], toolResources: new() @@ -34,10 +34,10 @@ await this.AgentsClient.CreateVectorStoreAsync( } }, metadata: new Dictionary() { { SampleMetadataKey, bool.TrueString } }); - AzureAIAgent agent = new(agentModel, this.AgentsClient); + AzureAIAgent agent = new(agentModel, this.Client); // Create a thread associated for the agent conversation. - Microsoft.SemanticKernel.Agents.AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + Microsoft.SemanticKernel.Agents.AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -49,9 +49,9 @@ await this.AgentsClient.CreateVectorStoreAsync( finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); - await this.AgentsClient.DeleteVectorStoreAsync(fileStore.Id); - await this.AgentsClient.DeleteFileAsync(fileInfo.Id); + await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.DeleteVectorStoreAsync(fileStore.Id); + await this.Client.DeleteFileAsync(fileInfo.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs index 194ae7b1638d..712b2f40e40f 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; @@ -24,17 +24,17 @@ public async Task UseOpenAPIToolWithAgent() string apiWeather = EmbeddedResource.Read("weather.json"); // Define the agent - Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [ new OpenApiToolDefinition("RestCountries", "Retrieve country information", BinaryData.FromString(apiCountries), new OpenApiAnonymousAuthDetails()), new OpenApiToolDefinition("Weather", "Retrieve weather by location", BinaryData.FromString(apiWeather), new OpenApiAnonymousAuthDetails()) ]); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - Microsoft.SemanticKernel.Agents.AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + Microsoft.SemanticKernel.Agents.AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -45,7 +45,7 @@ public async Task UseOpenAPIToolWithAgent() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs index 6eb018aecbe2..2ff178767dab 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs @@ -1,4 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; @@ -27,19 +28,19 @@ public async Task UseSingleAgentWithFunctionTools() KernelPlugin plugin = KernelPluginFactory.CreateFromType(); var tools = plugin.Select(f => f.ToToolDefinition(plugin.Name)); - Azure.AI.Projects.Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( model: TestConfiguration.AzureAI.ChatModelId, name: HostName, description: null, instructions: HostInstructions, tools: tools); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Add plugin to the agent's Kernel (same as direct Kernel usage). agent.Kernel.Plugins.Add(plugin); // Create a thread for the agent conversation. - AgentThread thread = new AzureAIAgentThread(this.AgentsClient, metadata: SampleMetadata); + AgentThread thread = new AzureAIAgentThread(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -52,7 +53,7 @@ public async Task UseSingleAgentWithFunctionTools() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index bc0922498775..d47a83ded3a6 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Core; using Azure.Identity; using Microsoft.Extensions.DependencyInjection; @@ -8,7 +8,6 @@ using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; using Plugins; -using Agent = Microsoft.SemanticKernel.Agents.Agent; namespace GettingStarted.AzureAgents; @@ -417,7 +416,7 @@ public async Task AzureAIAgentWithTemplate() public Step08_AzureAIAgent_Declarative(ITestOutputHelper output) : base(output) { var builder = Kernel.CreateBuilder(); - builder.Services.AddSingleton(this.Client); + builder.Services.AddSingleton(this.Client); this._kernel = builder.Build(); } diff --git a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step07_Assistant_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step07_Assistant_Declarative.cs index f0d193f300b7..33af88543254 100644 --- a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step07_Assistant_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step07_Assistant_Declarative.cs @@ -209,8 +209,8 @@ private async Task InvokeAgentAsync(Agent agent, string input, bool deleteAgent { if (deleteAgent) { - var openaiAgent = agent as OpenAIAssistantAgent; - await openaiAgent!.Client.DeleteAssistantAsync(openaiAgent.Id); + var openaiAgent = (OpenAIAssistantAgent)agent; + await openaiAgent.Client.DeleteAssistantAsync(openaiAgent.Id); } if (agentThread is not null) diff --git a/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs index 03d13cb3c7e0..407cae9feb97 100644 --- a/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System.ClientModel; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Identity; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; @@ -97,19 +97,19 @@ public Step10_MultiAgent_Declarative(ITestOutputHelper output) : base(output) OpenAIAssistantAgent.CreateAzureOpenAIClient(new ApiKeyCredential(this.ApiKey), new Uri(this.Endpoint!)) : OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(this.Endpoint!)); - var aiProjectClient = AzureAIAgent.CreateAzureAIClient(TestConfiguration.AzureAI.ConnectionString, new AzureCliCredential()); + var agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureCliCredential()); var builder = Kernel.CreateBuilder(); builder.Services.AddSingleton(openaiClient); - builder.Services.AddSingleton(aiProjectClient); + builder.Services.AddSingleton(agentsClient); AddChatCompletionToKernel(builder); this._kernel = builder.Build(); - this._kernelAgentFactory = new AggregatorKernelAgentFactory( - new ChatCompletionAgentFactory(), - new OpenAIAssistantAgentFactory(), - new AzureAIAgentFactory() - ); + this._kernelAgentFactory = + new AggregatorKernelAgentFactory( + new ChatCompletionAgentFactory(), + new OpenAIAssistantAgentFactory(), + new AzureAIAgentFactory()); } #region private diff --git a/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj b/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj index 2b0694f69986..441878455807 100644 --- a/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj +++ b/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj @@ -37,7 +37,8 @@ - + + diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs index e3b4e4bfe568..eb83d3529ab5 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Net.Http; -using Azure.AI.Projects; +using Azure; +using Azure.AI.Agents.Persistent; +using Azure.AI.Projects.OneDP; using Azure.Core; using Azure.Core.Pipeline; using Microsoft.SemanticKernel.Http; @@ -15,25 +18,45 @@ public sealed partial class AzureAIAgent : Agent /// /// Produces a . /// - /// The Azure AI Foundry project connection string, in the form `endpoint;subscription_id;resource_group_name;project_name`. + /// The Azure AI Foundry project endpoint. /// A credential used to authenticate to an Azure Service. /// A custom for HTTP requests. - public static AIProjectClient CreateAzureAIClient( - string connectionString, + public static PersistentAgentsClient CreateAgentsClient( + Uri endpoint, + AzureKeyCredential credential, + HttpClient? httpClient = null) + { + Verify.NotNull(endpoint, nameof(endpoint)); + Verify.NotNull(credential, nameof(credential)); + + PersistentAgentsClientOptions clientOptions = CreateAzureClientOptions(httpClient); + + return new PersistentAgentsClient(endpoint, credential, clientOptions); + } + + /// + /// Produces a . + /// + /// The Azure AI Foundry project endpoint. + /// A credential used to authenticate to an Azure Service. + /// A custom for HTTP requests. + public static PersistentAgentsClient CreateAgentsClient + ( + Uri endpoint, TokenCredential credential, HttpClient? httpClient = null) { - Verify.NotNullOrWhiteSpace(connectionString, nameof(connectionString)); + Verify.NotNull(endpoint, nameof(endpoint)); Verify.NotNull(credential, nameof(credential)); - AIProjectClientOptions clientOptions = CreateAzureClientOptions(httpClient); + PersistentAgentsClientOptions clientOptions = CreateAzureClientOptions(httpClient); - return new AIProjectClient(connectionString, credential, clientOptions); + return new PersistentAgentsClient(endpoint, credential, clientOptions); } - private static AIProjectClientOptions CreateAzureClientOptions(HttpClient? httpClient) + private static PersistentAgentsClientOptions CreateAzureClientOptions(HttpClient? httpClient) { - AIProjectClientOptions options = new(); + PersistentAgentsClientOptions options = new(); options.AddPolicy(new SemanticKernelHeadersPolicy(), HttpPipelinePosition.PerCall); diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs index 440dd0c74b65..1b4f9a7542da 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs @@ -5,13 +5,12 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.Extensions.Logging; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; using Microsoft.SemanticKernel.Agents.Extensions; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Diagnostics; -using AAIP = Azure.AI.Projects; namespace Microsoft.SemanticKernel.Agents.AzureAI; @@ -45,7 +44,7 @@ public static class Tools /// /// Gets the assistant definition. /// - public Azure.AI.Projects.Agent Definition { get; private init; } + public PersistentAgent Definition { get; private init; } /// /// Gets the polling behavior for run processing. @@ -61,8 +60,8 @@ public static class Tools /// An optional factory to produce the for the agent. /// The format of the prompt template used when "templateFactory" parameter is supplied. public AzureAIAgent( - Azure.AI.Projects.Agent model, - AgentsClient client, + PersistentAgent model, + PersistentAgentsClient client, IEnumerable? plugins = null, IPromptTemplateFactory? templateFactory = null, string? templateFormat = null) @@ -95,7 +94,7 @@ public AzureAIAgent( /// /// The associated client. /// - public AgentsClient Client { get; } + public PersistentAgentsClient Client { get; } /// /// Adds a message to the specified thread. @@ -431,7 +430,7 @@ protected override async Task RestoreChannelAsync(string channelSt this.Logger.LogAzureAIAgentRestoringChannel(nameof(RestoreChannelAsync), nameof(AzureAIChannel), threadId); - AAIP.AgentThread thread = await this.Client.GetThreadAsync(threadId, cancellationToken).ConfigureAwait(false); + PersistentAgentThread thread = await this.Client.GetThreadAsync(threadId, cancellationToken).ConfigureAwait(false); this.Logger.LogAzureAIAgentRestoredChannel(nameof(RestoreChannelAsync), nameof(AzureAIChannel), threadId); diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs index 0965819593e6..6f1e9645ed8f 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Azure; using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; namespace Microsoft.SemanticKernel.Agents.AzureAI; @@ -17,7 +18,7 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// public sealed class AzureAIAgentThread : AgentThread { - private readonly AgentsClient _client; + private readonly PersistentAgentsClient _client; private readonly IEnumerable? _messages; private readonly ToolResources? _toolResources; private readonly IReadOnlyDictionary? _metadata; @@ -34,7 +35,7 @@ public sealed class AzureAIAgentThread : AgentThread /// /// Metadata to attach to the underlying thread when it is created.. public AzureAIAgentThread( - AgentsClient client, + PersistentAgentsClient client, IEnumerable? messages = null, ToolResources? toolResources = null, IReadOnlyDictionary? metadata = null) @@ -52,7 +53,7 @@ public AzureAIAgentThread( /// /// The agents client to use for interacting with threads. /// The ID of an existing thread to resume. - public AzureAIAgentThread(AgentsClient client, string id) + public AzureAIAgentThread(PersistentAgentsClient client, string id) { Verify.NotNull(client); Verify.NotNull(id); diff --git a/dotnet/src/Agents/AzureAI/AzureAIChannel.cs b/dotnet/src/Agents/AzureAI/AzureAIChannel.cs index fa5991d4ace8..47ba25794a75 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIChannel.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIChannel.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; using Microsoft.SemanticKernel.Agents.Extensions; using Microsoft.SemanticKernel.Diagnostics; @@ -12,7 +12,7 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// /// A specialization for use with . /// -internal sealed class AzureAIChannel(AgentsClient client, string threadId) +internal sealed class AzureAIChannel(PersistentAgentsClient client, string threadId) : AgentChannel { /// diff --git a/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs b/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs index 4d9b55515192..f1536a964203 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs @@ -1,8 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Azure.AI.Projects; +using Azure.AI.Projects.OneDP; using Azure.Core; using Azure.Core.Pipeline; using Microsoft.SemanticKernel.Http; @@ -12,6 +14,7 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// /// Provides an for use by . /// +[Obsolete("Use AzureAIAgent.CreateAzureAIClient(...)")] public sealed class AzureAIClientProvider { private AgentsClient? _agentsClient; @@ -34,26 +37,26 @@ public sealed class AzureAIClientProvider private AzureAIClientProvider(AIProjectClient client, IEnumerable keys) { this.Client = client; - this.ConfigurationKeys = keys.ToArray(); + this.ConfigurationKeys = [.. keys]; } /// /// Produces a . /// - /// The Azure AI Foundry project connection string, in the form `endpoint;subscription_id;resource_group_name;project_name`. + /// The Azure AI Foundry project connection string, in the form `endpoint;subscription_id;resource_group_name;project_name`. /// A credential used to authenticate to an Azure Service. /// A custom for HTTP requests. - public static AzureAIClientProvider FromConnectionString( - string connectionString, + public static AzureAIClientProvider FromEndpoint( + Uri endpoint, TokenCredential credential, HttpClient? httpClient = null) { - Verify.NotNullOrWhiteSpace(connectionString, nameof(connectionString)); + Verify.NotNull(endpoint, nameof(endpoint)); Verify.NotNull(credential, nameof(credential)); AIProjectClientOptions clientOptions = CreateAzureClientOptions(httpClient); - return new(new AIProjectClient(connectionString, credential, clientOptions), CreateConfigurationKeys(connectionString, httpClient)); + return new(new AIProjectClient(endpoint, credential, clientOptions), CreateConfigurationKeys(endpoint, httpClient)); } /// @@ -86,9 +89,9 @@ internal static AIProjectClientOptions CreateAzureClientOptions(HttpClient? http return options; } - private static IEnumerable CreateConfigurationKeys(string connectionString, HttpClient? httpClient) + private static IEnumerable CreateConfigurationKeys(Uri endpoint, HttpClient? httpClient) { - yield return connectionString; + yield return endpoint.ToString(); if (httpClient is not null) { diff --git a/dotnet/src/Agents/AzureAI/AzureAIThreadMessageFactory.cs b/dotnet/src/Agents/AzureAI/AzureAIThreadMessageFactory.cs index d37242c522ed..c5199fb146c2 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIThreadMessageFactory.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIThreadMessageFactory.cs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using System.Collections.Generic; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; namespace Microsoft.SemanticKernel.Agents.AzureAI; diff --git a/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs b/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs index 5bd22137292f..fd1bea827d52 100644 --- a/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs +++ b/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs @@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; namespace Microsoft.SemanticKernel.Agents.AzureAI; @@ -33,10 +33,9 @@ public AzureAIAgentFactory() if (agentDefinition.Type?.Equals(AzureAIAgentType, System.StringComparison.Ordinal) ?? false) { - var projectClient = agentDefinition.GetAIProjectClient(kernel); + var client = agentDefinition.GetAgentsClient(kernel); - AgentsClient client = projectClient.GetAgentsClient(); - Azure.AI.Projects.Agent agent; + PersistentAgent agent; if (!string.IsNullOrEmpty(agentDefinition.Id)) { // Get an existing agent diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs index 1f11bc5f0260..940fc6b11c18 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel.Http; @@ -24,8 +24,8 @@ internal static class AgentDefinitionExtensions private const string OpenApiType = "openapi"; private const string SharepointGroundingType = "sharepoint_grounding"; - private static readonly string[] s_validToolTypes = new string[] - { + private static readonly string[] s_validToolTypes = + [ AzureAISearchType, AzureFunctionType, BingGroundingType, @@ -35,9 +35,9 @@ internal static class AgentDefinitionExtensions MicrosoftFabricType, OpenApiType, SharepointGroundingType - }; + ]; - private const string ConnectionString = "connection_string"; + private const string Endpoint = "endpoint"; /// /// Return the Azure AI tool definitions which corresponds with the provided . @@ -108,11 +108,11 @@ public static ToolResources GetAzureToolResources(this AgentDefinition agentDefi } /// - /// Return the to be used with the specified . + /// Return the to be used with the specified . /// - /// Agent definition which will be used to provide connection for the . - /// Kernel instance which will be used to resolve a default . - public static AIProjectClient GetAIProjectClient(this AgentDefinition agentDefinition, Kernel kernel) + /// Agent definition which will be used to provide connection for the . + /// Kernel instance which will be used to resolve a default . + public static PersistentAgentsClient GetAgentsClient(this AgentDefinition agentDefinition, Kernel kernel) { Verify.NotNull(agentDefinition); @@ -120,21 +120,20 @@ public static AIProjectClient GetAIProjectClient(this AgentDefinition agentDefin var connection = agentDefinition?.Model?.Connection; if (connection is not null) { - if (connection.ExtensionData.TryGetValue(ConnectionString, out var value) && value is string connectionString) + if (connection.ExtensionData.TryGetValue(Endpoint, out var value) && value is string endpoint) { #pragma warning disable CA2000 // Dispose objects before losing scope, not relevant because the HttpClient is created and may be used elsewhere var httpClient = HttpClientProvider.GetHttpClient(kernel.Services); #pragma warning restore CA2000 // Dispose objects before losing scope - AIProjectClientOptions clientOptions = AzureAIClientProvider.CreateAzureClientOptions(httpClient); var tokenCredential = kernel.Services.GetRequiredService(); - return new(connectionString, tokenCredential, clientOptions); + return AzureAIAgent.CreateAgentsClient(new Uri(endpoint), tokenCredential, httpClient); } } // Return the client registered on the kernel - var client = kernel.GetAllServices().FirstOrDefault(); - return (AIProjectClient?)client ?? throw new InvalidOperationException("AzureAI project client not found."); + var client = kernel.GetAllServices().FirstOrDefault(); + return (PersistentAgentsClient?)client ?? throw new InvalidOperationException("AzureAI project client not found."); } #region private diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs index 733494140711..daba5e119f34 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; namespace Microsoft.SemanticKernel.Agents.AzureAI.Extensions; @@ -19,9 +18,9 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI.Extensions; internal static class AgentRunExtensions { public static async IAsyncEnumerable GetStepsAsync( - this AgentsClient client, - ThreadRun run, - [EnumeratorCancellation] CancellationToken cancellationToken) + this PersistentAgentsClient client, + ThreadRun run, + [EnumeratorCancellation] CancellationToken cancellationToken) { PageableList? steps = null; do @@ -36,7 +35,7 @@ public static async IAsyncEnumerable GetStepsAsync( } public static async Task CreateAsync( - this AgentsClient client, + this PersistentAgentsClient client, string threadId, AzureAIAgent agent, string? instructions, @@ -49,11 +48,11 @@ public static async Task CreateAsync( return await client.CreateRunAsync( threadId, - agent.Definition.Id, + agent.Id, overrideModelName: invocationOptions?.ModelName, overrideInstructions: invocationOptions?.OverrideInstructions ?? instructions, additionalInstructions: invocationOptions?.AdditionalInstructions, - additionalMessages: AgentMessageFactory.GetThreadMessages(invocationOptions?.AdditionalMessages).ToArray(), + additionalMessages: [.. AgentMessageFactory.GetThreadMessages(invocationOptions?.AdditionalMessages)], overrideTools: tools, stream: false, temperature: invocationOptions?.Temperature, @@ -87,7 +86,7 @@ await client.CreateRunAsync( } public static IAsyncEnumerable CreateStreamingAsync( - this AgentsClient client, + this PersistentAgentsClient client, string threadId, AzureAIAgent agent, string? instructions, @@ -100,11 +99,11 @@ public static IAsyncEnumerable CreateStreamingAsync( return client.CreateRunStreamingAsync( threadId, - agent.Definition.Id, + agent.Id, overrideModelName: invocationOptions?.ModelName, overrideInstructions: invocationOptions?.OverrideInstructions ?? instructions, additionalInstructions: invocationOptions?.AdditionalInstructions, - additionalMessages: AgentMessageFactory.GetThreadMessages(invocationOptions?.AdditionalMessages).ToArray(), + additionalMessages: [.. AgentMessageFactory.GetThreadMessages(invocationOptions?.AdditionalMessages)], overrideTools: tools, temperature: invocationOptions?.Temperature, topP: invocationOptions?.TopP, diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs index 5429daea86b3..c88f897babc1 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; namespace Microsoft.SemanticKernel.Agents.AzureAI; diff --git a/dotnet/src/Agents/AzureAI/Extensions/KernelFunctionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/KernelFunctionExtensions.cs index e6b9c722eabb..39ed1b4bac8c 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/KernelFunctionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/KernelFunctionExtensions.cs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using System; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; namespace Microsoft.SemanticKernel.Agents.AzureAI; diff --git a/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs b/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs index 621e364acf6a..30fa96ba2024 100644 --- a/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs +++ b/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System.Collections.Generic; using System.Linq; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.ChatCompletion; namespace Microsoft.SemanticKernel.Agents.AzureAI.Internal; @@ -35,7 +35,7 @@ public static IEnumerable GetAttachments(ChatMessageContent m .OfType() .Select( fileContent => - new MessageAttachment(fileContent.FileId, GetToolDefinition(fileContent.Tools).ToList())); + new MessageAttachment(fileContent.FileId, [.. GetToolDefinition(fileContent.Tools)])); } /// @@ -58,7 +58,7 @@ public static IEnumerable GetThreadMessages(IEnumerableThe assistant client /// The to monitor for cancellation requests. The default is . /// The thread identifier - public static async Task CreateThreadAsync(AgentsClient client, CancellationToken cancellationToken = default) + public static async Task CreateThreadAsync(PersistentAgentsClient client, CancellationToken cancellationToken = default) { - AAIP.AgentThread thread = await client.CreateThreadAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + PersistentAgentThread thread = await client.CreateThreadAsync(cancellationToken: cancellationToken).ConfigureAwait(false); return thread.Id; } @@ -59,7 +58,7 @@ public static async Task CreateThreadAsync(AgentsClient client, Cancella /// The message to add /// The to monitor for cancellation requests. The default is . /// if a system message is present, without taking any other action - public static async Task CreateMessageAsync(AgentsClient client, string threadId, ChatMessageContent message, CancellationToken cancellationToken) + public static async Task CreateMessageAsync(PersistentAgentsClient client, string threadId, ChatMessageContent message, CancellationToken cancellationToken) { if (message.Items.Any(i => i is FunctionCallContent)) { @@ -89,7 +88,7 @@ await client.CreateMessageAsync( /// The order to return messages in. /// The to monitor for cancellation requests. The default is . /// Asynchronous enumeration of messages. - public static async IAsyncEnumerable GetMessagesAsync(AgentsClient client, string threadId, ListSortOrder? messageOrder, [EnumeratorCancellation] CancellationToken cancellationToken) + public static async IAsyncEnumerable GetMessagesAsync(PersistentAgentsClient client, string threadId, ListSortOrder? messageOrder, [EnumeratorCancellation] CancellationToken cancellationToken) { Dictionary agentNames = []; // Cache agent names by their identifier @@ -105,7 +104,7 @@ public static async IAsyncEnumerable GetMessagesAsync(Agents if (!string.IsNullOrWhiteSpace(message.AssistantId) && !agentNames.TryGetValue(message.AssistantId, out assistantName)) { - Azure.AI.Projects.Agent assistant = await client.GetAgentAsync(message.AssistantId, cancellationToken).ConfigureAwait(false); + PersistentAgent assistant = await client.GetAgentAsync(message.AssistantId, cancellationToken).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(assistant.Name)) { agentNames.Add(assistant.Id, assistant.Name); @@ -140,7 +139,7 @@ public static async IAsyncEnumerable GetMessagesAsync(Agents /// Asynchronous enumeration of messages. public static async IAsyncEnumerable<(bool IsVisible, ChatMessageContent Message)> InvokeAsync( AzureAIAgent agent, - AgentsClient client, + PersistentAgentsClient client, string threadId, AzureAIInvocationOptions? invocationOptions, ILogger logger, @@ -186,7 +185,7 @@ public static async IAsyncEnumerable GetMessagesAsync(Agents throw new KernelException($"Agent Failure - Run terminated: {run.Status} [{run.Id}]: {run.LastError?.Message ?? "Unknown"}"); } - RunStep[] steps = await client.GetStepsAsync(run, cancellationToken).ToArrayAsync(cancellationToken).ConfigureAwait(false); + RunStep[] steps = await client.GetStepsAsync(run, cancellationToken: cancellationToken).ToArrayAsync(cancellationToken).ConfigureAwait(false); // Is tool action required? if (run.Status == RunStatus.RequiresAction) @@ -371,7 +370,7 @@ async Task PollRunStatusAsync() /// public static async IAsyncEnumerable InvokeStreamingAsync( AzureAIAgent agent, - AgentsClient client, + PersistentAgentsClient client, string threadId, IList? messages, AzureAIInvocationOptions? invocationOptions, @@ -828,7 +827,7 @@ private static ToolOutput[] GenerateToolOutputs(FunctionResultContent[] function return toolOutputs; } - private static async Task RetrieveMessageAsync(AgentsClient client, string threadId, string messageId, TimeSpan syncDelay, CancellationToken cancellationToken) + private static async Task RetrieveMessageAsync(PersistentAgentsClient client, string threadId, string messageId, TimeSpan syncDelay, CancellationToken cancellationToken) { ThreadMessage? message = null; diff --git a/dotnet/src/Agents/AzureAI/Logging/AgentThreadActionsLogMessages.cs b/dotnet/src/Agents/AzureAI/Logging/AgentThreadActionsLogMessages.cs index 974af70205eb..3e21f533bbee 100644 --- a/dotnet/src/Agents/AzureAI/Logging/AgentThreadActionsLogMessages.cs +++ b/dotnet/src/Agents/AzureAI/Logging/AgentThreadActionsLogMessages.cs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using System.Diagnostics.CodeAnalysis; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.Extensions.Logging; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; diff --git a/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs b/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs index 88470519ac77..c84265f70f63 100644 --- a/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs +++ b/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs @@ -140,22 +140,20 @@ public static OpenAIClient GetOpenAIClient(this AgentDefinition agentDefinition, if (connection.Type.Equals(OpenAI, StringComparison.OrdinalIgnoreCase)) { - OpenAIClientOptions clientOptions = OpenAIClientProvider.CreateOpenAIClientOptions(connection.TryGetEndpoint(), httpClient); - return new OpenAIClient(connection.GetApiKeyCredential(), clientOptions); + return OpenAIAssistantAgent.CreateOpenAIClient(connection.GetApiKeyCredential(), connection.TryGetEndpoint(), httpClient); } else if (connection.Type.Equals(AzureOpenAI, StringComparison.OrdinalIgnoreCase)) { var endpoint = connection.TryGetEndpoint(); Verify.NotNull(endpoint, "Endpoint must be specified when using Azure OpenAI."); - AzureOpenAIClientOptions clientOptions = OpenAIClientProvider.CreateAzureClientOptions(httpClient); if (connection.ExtensionData.TryGetValue(ApiKey, out var apiKey) && apiKey is not null) { - return new AzureOpenAIClient(endpoint, connection.GetApiKeyCredential(), clientOptions); + return OpenAIAssistantAgent.CreateAzureOpenAIClient(connection.GetApiKeyCredential(), endpoint, httpClient); } var tokenCredential = kernel.Services.GetRequiredService(); - return new AzureOpenAIClient(endpoint, tokenCredential, clientOptions); + return OpenAIAssistantAgent.CreateAzureOpenAIClient(tokenCredential, endpoint, httpClient); } throw new InvalidOperationException($"Invalid OpenAI client type '{connection.Type}' was specified."); diff --git a/dotnet/src/Agents/OpenAI/OpenAIClientProvider.cs b/dotnet/src/Agents/OpenAI/OpenAIClientProvider.cs index ebb8fcdce542..9c157d9fa125 100644 --- a/dotnet/src/Agents/OpenAI/OpenAIClientProvider.cs +++ b/dotnet/src/Agents/OpenAI/OpenAIClientProvider.cs @@ -19,6 +19,7 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI; /// Provides an for use by . /// [Experimental("SKEXP0110")] +[Obsolete("Use OpenAIAssistantAgent.CreateAzureOpenAIClient(...) or OpenAIAssistantAgent.CreateOpenAIClient(...)")] public sealed class OpenAIClientProvider { /// diff --git a/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs index 96ddfb046896..17e93948dd05 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; using System.Net.Http; -using Azure.AI.Projects; +using Azure.AI.Projects.OneDP; using Azure.Identity; using Microsoft.SemanticKernel.Agents.AzureAI; using Moq; @@ -21,7 +21,7 @@ public class AzureAIClientProviderTests public void VerifyAzureAIClientProviderDefault() { // Act - AzureAIClientProvider provider = AzureAIClientProvider.FromConnectionString("test;test;test;test", new AzureCliCredential()); + AzureAIClientProvider provider = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential()); // Assert Assert.NotNull(provider.Client); @@ -37,7 +37,7 @@ public void VerifyAzureAIClientProviderWithHttpClient() using HttpClient httpClient = new() { BaseAddress = new Uri("http://myproxy:9819") }; // Act - AzureAIClientProvider provider = AzureAIClientProvider.FromConnectionString("test;test;test;test", new AzureCliCredential(), httpClient); + AzureAIClientProvider provider = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential(), httpClient); // Assert Assert.NotNull(provider.Client); @@ -47,7 +47,7 @@ public void VerifyAzureAIClientProviderWithHttpClient() httpClientWithHeaders.DefaultRequestHeaders.Add("X-Test", "Test"); // Act - AzureAIClientProvider providerWithHeaders = AzureAIClientProvider.FromConnectionString("test;test;test;test", new AzureCliCredential(), httpClientWithHeaders); + AzureAIClientProvider providerWithHeaders = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential(), httpClientWithHeaders); // Assert Assert.NotNull(providerWithHeaders.Client); diff --git a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs index c21fbfb03f67..5b46b241d65a 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs @@ -4,7 +4,8 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; +using Azure.AI.Projects.OneDP; using Azure.Core.Pipeline; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; @@ -32,12 +33,14 @@ public AzureAIAgentFactoryTests() this._httpClient = new HttpClient(this._messageHandlerStub, disposeHandler: false); var builder = Kernel.CreateBuilder(); - var client = new AIProjectClient( - "endpoint;subscription_id;resource_group_name;project_name", + var client = new PersistentAgentsClient( + new Uri("https://test"), new FakeTokenCredential(), - new AIProjectClientOptions() - { Transport = new HttpClientTransport(this._httpClient) }); - builder.Services.AddSingleton(client); + new PersistentAgentsClientOptions + { + Transport = new HttpClientTransport(this._httpClient) + }); + builder.Services.AddSingleton(client); this._kernel = builder.Build(); } diff --git a/dotnet/src/Agents/UnitTests/AzureAI/Extensions/KernelFunctionExtensionsTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/Extensions/KernelFunctionExtensionsTests.cs index cb8fe8415b97..298d22eae529 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/Extensions/KernelFunctionExtensionsTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/Extensions/KernelFunctionExtensionsTests.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; using System.ComponentModel; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.AzureAI; using Xunit; diff --git a/dotnet/src/Agents/UnitTests/AzureAI/Internal/AgentMessageFactoryTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/Internal/AgentMessageFactoryTests.cs index c42de6fc38a2..99e47fb9f155 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/Internal/AgentMessageFactoryTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/Internal/AgentMessageFactoryTests.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. using System; using System.Linq; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; using Microsoft.SemanticKernel.ChatCompletion; diff --git a/dotnet/src/Agents/UnitTests/OpenAI/Definition/OpenAIAssistantAgentFactoryTests.cs b/dotnet/src/Agents/UnitTests/OpenAI/Definition/OpenAIAssistantAgentFactoryTests.cs index 6dcb0280bec7..72c45009084c 100644 --- a/dotnet/src/Agents/UnitTests/OpenAI/Definition/OpenAIAssistantAgentFactoryTests.cs +++ b/dotnet/src/Agents/UnitTests/OpenAI/Definition/OpenAIAssistantAgentFactoryTests.cs @@ -31,8 +31,7 @@ public OpenAIAssistantAgentFactoryTests() this._messageHandlerStub = new HttpMessageHandlerStub(); this._httpClient = new HttpClient(this._messageHandlerStub, disposeHandler: false); - OpenAIClientOptions clientOptions = OpenAIClientProvider.CreateOpenAIClientOptions(endpoint: null, httpClient: this._httpClient); - OpenAIClient openAIClient = new(new ApiKeyCredential("fakekey"), clientOptions); + OpenAIClient openAIClient = OpenAIAssistantAgent.CreateOpenAIClient(new ApiKeyCredential("fakekey"), httpClient: this._httpClient); var builder = Kernel.CreateBuilder(); builder.Services.AddSingleton(openAIClient); diff --git a/dotnet/src/Agents/UnitTests/OpenAI/Extensions/AssistantClientExtensionsTests.cs b/dotnet/src/Agents/UnitTests/OpenAI/Extensions/AssistantClientExtensionsTests.cs index f1cdd1e429cd..6e87bb686555 100644 --- a/dotnet/src/Agents/UnitTests/OpenAI/Extensions/AssistantClientExtensionsTests.cs +++ b/dotnet/src/Agents/UnitTests/OpenAI/Extensions/AssistantClientExtensionsTests.cs @@ -8,6 +8,7 @@ using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.OpenAI; using Microsoft.SemanticKernel.ChatCompletion; +using OpenAI; using OpenAI.Assistants; using Xunit; @@ -22,7 +23,7 @@ public sealed class AssistantClientExtensionsTests : IDisposable private readonly HttpMessageHandlerStub _messageHandlerStub; private readonly HttpClient _httpClient; - private readonly OpenAIClientProvider _clientProvider; + private readonly OpenAIClient _client; /// /// Verify the assistant creation with default values. @@ -34,7 +35,7 @@ public async Task VerifyCreateAssistantAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.AssistantDefinition(ModelValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync(modelId: ModelValue); + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync(modelId: ModelValue); // Assert Assert.NotNull(definition); @@ -61,7 +62,7 @@ public async Task VerifyCreateAssistantWithIdentityAsync() description: DescriptionValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: ModelValue, name: NameValue, instructions: InstructionsValue, @@ -99,7 +100,7 @@ public async Task VerifyCreateAssistantWithTemplateAsync() description: DescriptionValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantFromTemplateAsync(modelId: ModelValue, templateConfig); + Assistant definition = await this._client.GetAssistantClient().CreateAssistantFromTemplateAsync(modelId: ModelValue, templateConfig); // Assert Assert.NotNull(definition); @@ -120,7 +121,7 @@ public async Task VerifyCreateAssistantWithCodeInterpreterAsync() OpenAIAssistantResponseContent.AssistantDefinition(ModelValue, enableCodeInterpreter: true)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: ModelValue, enableCodeInterpreter: true); @@ -143,7 +144,7 @@ public async Task VerifyCreateAssistantWithCodeInterpreterFilesAsync() OpenAIAssistantResponseContent.AssistantDefinition(ModelValue, codeInterpreterFileIds: fileIds)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: ModelValue, codeInterpreterFileIds: fileIds); @@ -167,7 +168,7 @@ public async Task VerifyCreateAssistantWithFileSearchAsync() OpenAIAssistantResponseContent.AssistantDefinition(ModelValue, enableFileSearch: true)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: ModelValue, enableFileSearch: true); @@ -190,7 +191,7 @@ public async Task VerifyCreateAssistantWithVectorStoreAsync() OpenAIAssistantResponseContent.AssistantDefinition(ModelValue, vectorStoreId: VectorStoreValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: ModelValue, vectorStoreId: VectorStoreValue); @@ -214,7 +215,7 @@ public async Task VerifyCreateAssistantWithTemperatureAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.AssistantDefinition("testmodel", temperature: TemperatureValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: "testmodel", temperature: TemperatureValue); @@ -235,7 +236,7 @@ public async Task VerifyCreateAssistantWithTopPAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.AssistantDefinition("testmodel", topP: TopPValue)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: "testmodel", topP: TopPValue); @@ -261,7 +262,7 @@ public async Task VerifyCreateAssistantWithMetadataAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.AssistantDefinition("testmodel", metadata: metadata)); // Act - Assistant definition = await this._clientProvider.AssistantClient.CreateAssistantAsync( + Assistant definition = await this._client.GetAssistantClient().CreateAssistantAsync( modelId: "testmodel", metadata: metadata); @@ -280,7 +281,7 @@ public async Task VerifyDeleteAssistantAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.DeleteAgent); // Act - AssistantDeletionResult result = await this._clientProvider.AssistantClient.DeleteAssistantAsync("testid"); + AssistantDeletionResult result = await this._client.GetAssistantClient().DeleteAssistantAsync("testid"); // Assert Assert.True(result.Deleted); @@ -296,7 +297,7 @@ public async Task VerifyCreateThreadAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); // Act - string threadId = await this._clientProvider.AssistantClient.CreateThreadAsync(messages: null); + string threadId = await this._client.GetAssistantClient().CreateThreadAsync(messages: null); // Assert Assert.NotNull(threadId); @@ -312,7 +313,7 @@ public async Task VerifyCreateThreadWithMessagesAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); // Act - string threadId = await this._clientProvider.AssistantClient.CreateThreadAsync(messages: [new ChatMessageContent(AuthorRole.User, "test")]); + string threadId = await this._client.GetAssistantClient().CreateThreadAsync(messages: [new ChatMessageContent(AuthorRole.User, "test")]); // Assert Assert.NotNull(threadId); @@ -329,7 +330,7 @@ public async Task VerifyCreateThreadWithMetadataAsync() Dictionary metadata = new() { { "a", "1" }, { "b", "2" } }; // Act - string threadId = await this._clientProvider.AssistantClient.CreateThreadAsync(metadata: metadata); + string threadId = await this._client.GetAssistantClient().CreateThreadAsync(metadata: metadata); // Assert Assert.NotNull(threadId); @@ -349,7 +350,7 @@ public AssistantClientExtensionsTests() { this._messageHandlerStub = new HttpMessageHandlerStub(); this._httpClient = new HttpClient(this._messageHandlerStub, disposeHandler: false); - this._clientProvider = OpenAIClientProvider.ForOpenAI(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); + this._client = OpenAIAssistantAgent.CreateOpenAIClient(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); } private void SetupResponse(HttpStatusCode statusCode, string content) => diff --git a/dotnet/src/Agents/UnitTests/OpenAI/Extensions/OpenAIClientExtensionsTests.cs b/dotnet/src/Agents/UnitTests/OpenAI/Extensions/OpenAIClientExtensionsTests.cs index ce03e8f5843e..92b8279629e6 100644 --- a/dotnet/src/Agents/UnitTests/OpenAI/Extensions/OpenAIClientExtensionsTests.cs +++ b/dotnet/src/Agents/UnitTests/OpenAI/Extensions/OpenAIClientExtensionsTests.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.SemanticKernel.Agents.OpenAI; +using OpenAI; using OpenAI.VectorStores; using Xunit; @@ -20,7 +21,7 @@ public sealed class OpenAIClientExtensionsTests : IDisposable { private readonly HttpMessageHandlerStub _messageHandlerStub; private readonly HttpClient _httpClient; - private readonly OpenAIClientProvider _clientProvider; + private readonly OpenAIClient _client; /// /// Verify the default creation of vector-store. @@ -33,7 +34,7 @@ public async Task VerifyCreateDefaultVectorStoreAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateVectorStore); // Act - string storeId = await this._clientProvider.Client.CreateVectorStoreAsync(fileIds, waitUntilCompleted: false); + string storeId = await this._client.CreateVectorStoreAsync(fileIds, waitUntilCompleted: false); // Assert Assert.NotNull(storeId); @@ -56,7 +57,7 @@ public async Task VerifyCreateVectorStoreAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateVectorStore); // Act - string storeId = await this._clientProvider.Client.CreateVectorStoreAsync( + string storeId = await this._client.CreateVectorStoreAsync( fileIds, waitUntilCompleted: false, storeName: "test-store", @@ -79,7 +80,7 @@ public async Task VerifyUploadFileAsync() // Act await using MemoryStream stream = new(Encoding.UTF8.GetBytes("test")); - string fileId = await this._clientProvider.Client.UploadAssistantFileAsync(stream, "text.txt"); + string fileId = await this._client.UploadAssistantFileAsync(stream, "text.txt"); // Assert Assert.NotNull(fileId); @@ -95,7 +96,7 @@ public async Task VerifyDeleteFileAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.DeleteFile); // Act - bool isDeleted = await this._clientProvider.Client.DeleteFileAsync("file-id"); + bool isDeleted = await this._client.DeleteFileAsync("file-id"); // Assert Assert.True(isDeleted); @@ -111,7 +112,7 @@ public async Task VerifyDeleteVectorStoreAsync() this.SetupResponse(HttpStatusCode.OK, OpenAIAssistantResponseContent.DeleteVectorStore); // Act - bool isDeleted = await this._clientProvider.Client.DeleteVectorStoreAsync("store-id"); + bool isDeleted = await this._client.DeleteVectorStoreAsync("store-id"); // Assert Assert.True(isDeleted); @@ -131,7 +132,7 @@ public OpenAIClientExtensionsTests() { this._messageHandlerStub = new HttpMessageHandlerStub(); this._httpClient = new HttpClient(this._messageHandlerStub, disposeHandler: false); - this._clientProvider = OpenAIClientProvider.ForOpenAI(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); + this._client = OpenAIAssistantAgent.CreateOpenAIClient(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); } private void SetupResponse(HttpStatusCode statusCode, string content) => diff --git a/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentTests.cs b/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentTests.cs index a5bd93969b41..73b6933c2a47 100644 --- a/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentTests.cs +++ b/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentTests.cs @@ -309,7 +309,7 @@ public async Task VerifyOpenAIAssistantAgentRetrievalAsync() OpenAIAssistantAgent agent = await OpenAIAssistantAgent.RetrieveAsync( - this.CreateTestProvider(), + this.CreateTestClient(), "#id", this._emptyKernel); @@ -330,7 +330,7 @@ public async Task VerifyOpenAIAssistantAgentRetrievalWithFactoryAsync() OpenAIAssistantAgent agent = await OpenAIAssistantAgent.RetrieveAsync( - this.CreateTestProvider(), + this.CreateTestClient(), "#id", this._emptyKernel, [], @@ -748,7 +748,7 @@ public async Task VerifyOpenAIAssistantAgentListDefinitionAsync() // Act var messages = await OpenAIAssistantAgent.ListDefinitionsAsync( - this.CreateTestProvider()).ToArrayAsync(); + this.CreateTestClient()).ToArrayAsync(); // Assert Assert.Equal(7, messages.Length); @@ -761,7 +761,7 @@ await OpenAIAssistantAgent.ListDefinitionsAsync( // Act messages = await OpenAIAssistantAgent.ListDefinitionsAsync( - this.CreateTestProvider()).ToArrayAsync(); + this.CreateTestClient()).ToArrayAsync(); // Assert Assert.Equal(4, messages.Length); } @@ -823,7 +823,7 @@ private async Task VerifyAgentCreationAsync(OpenAIAssistantDefinition definition OpenAIAssistantAgent agent = await OpenAIAssistantAgent.CreateAsync( - this.CreateTestProvider(), + this.CreateTestClient(), definition, this._emptyKernel); @@ -839,7 +839,7 @@ private async Task VerifyAgentTemplateAsync( OpenAIAssistantAgent agent = await OpenAIAssistantAgent.CreateFromTemplateAsync( - this.CreateTestProvider(), + this.CreateTestClient(), capabilities, this._emptyKernel, [], @@ -938,12 +938,12 @@ private Task CreateAgentAsync() return OpenAIAssistantAgent.CreateAsync( - this.CreateTestProvider(), + this.CreateTestClient(), definition, this._emptyKernel); } - private OpenAIClientProvider CreateTestProvider(bool targetAzure = false) + private OpenAIClientProvider CreateTestClient(bool targetAzure = false) => targetAzure ? OpenAIClientProvider.ForAzureOpenAI(apiKey: new ApiKeyCredential("fakekey"), endpoint: new Uri("https://localhost"), this._httpClient) : OpenAIClientProvider.ForOpenAI(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); diff --git a/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentThreadTests.cs b/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentThreadTests.cs index c7a520ea4295..5b2c5bc18abe 100644 --- a/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentThreadTests.cs +++ b/dotnet/src/Agents/UnitTests/OpenAI/OpenAIAssistantAgentThreadTests.cs @@ -9,6 +9,7 @@ using Microsoft.SemanticKernel.Agents.OpenAI; using Microsoft.SemanticKernel.ChatCompletion; using Moq; +using OpenAI; using OpenAI.Assistants; using Xunit; @@ -75,10 +76,9 @@ public async Task CreateShouldInvokeClientAsync() // Arrange this._messageHandlerStub.SetupResponses(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); - var provider = this.CreateTestProvider(); - var assistantClient = provider.AssistantClient; + var client = this.CreateTestClient(); - var thread = new OpenAIAssistantAgentThread(assistantClient); + var thread = new OpenAIAssistantAgentThread(client.GetAssistantClient()); // Act await thread.CreateAsync(); @@ -97,10 +97,9 @@ public async Task CreateWithOptionsShouldInvokeClientAsync() // Arrange this._messageHandlerStub.SetupResponses(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); - var provider = this.CreateTestProvider(); - var assistantClient = provider.AssistantClient; + var client = this.CreateTestClient(); - var thread = new OpenAIAssistantAgentThread(assistantClient, new ThreadCreationOptions()); + var thread = new OpenAIAssistantAgentThread(client.GetAssistantClient(), new ThreadCreationOptions()); // Act await thread.CreateAsync(); @@ -119,10 +118,9 @@ public async Task CreateWithParamsShouldInvokeClientAsync() // Arrange this._messageHandlerStub.SetupResponses(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); - var provider = this.CreateTestProvider(); - var assistantClient = provider.AssistantClient; + var client = this.CreateTestClient(); - var thread = new OpenAIAssistantAgentThread(assistantClient, [new ChatMessageContent(AuthorRole.User, "Hello")]); + var thread = new OpenAIAssistantAgentThread(client.GetAssistantClient(), [new ChatMessageContent(AuthorRole.User, "Hello")]); // Act await thread.CreateAsync(); @@ -142,10 +140,9 @@ public async Task DeleteShouldInvokeClientAsync() this._messageHandlerStub.SetupResponses(HttpStatusCode.OK, OpenAIAssistantResponseContent.CreateThread); this._messageHandlerStub.SetupResponses(HttpStatusCode.OK, OpenAIAssistantResponseContent.DeleteThread); - var provider = this.CreateTestProvider(); - var assistantClient = provider.AssistantClient; + var client = this.CreateTestClient(); - var thread = new OpenAIAssistantAgentThread(assistantClient); + var thread = new OpenAIAssistantAgentThread(client.GetAssistantClient()); await thread.CreateAsync(); // Act @@ -164,6 +161,6 @@ public void Dispose() GC.SuppressFinalize(this); } - private OpenAIClientProvider CreateTestProvider() - => OpenAIClientProvider.ForOpenAI(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); + private OpenAIClient CreateTestClient() + => OpenAIAssistantAgent.CreateOpenAIClient(apiKey: new ApiKeyCredential("fakekey"), endpoint: null, this._httpClient); } diff --git a/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs b/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs index eff4b579ebf0..db79cc9ea366 100644 --- a/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs +++ b/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. using System; -using System.ClientModel; using System.Net; using System.Net.Http; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Core.Pipeline; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; @@ -40,17 +39,18 @@ public AgentYamlTests() var builder = Kernel.CreateBuilder(); // Add OpenAI client - OpenAIClientOptions clientOptions = OpenAIClientProvider.CreateOpenAIClientOptions(endpoint: null, httpClient: this._httpClient); - OpenAIClient openAIClient = new(new ApiKeyCredential("fakekey"), clientOptions); - builder.Services.AddSingleton(openAIClient); + OpenAIClient openAIClient = OpenAIAssistantAgent.CreateOpenAIClient(new System.ClientModel.ApiKeyCredential("fakekey"), httpClient: this._httpClient); + builder.Services.AddSingleton(openAIClient); // Add Azure AI agents client - var client = new AIProjectClient( - "endpoint;subscription_id;resource_group_name;project_name", + var client = new PersistentAgentsClient( + new Uri("https://endpoint"), new FakeTokenCredential(), - new AIProjectClientOptions() - { Transport = new HttpClientTransport(this._httpClient) }); - builder.Services.AddSingleton(client); + new PersistentAgentsClientOptions + { + Transport = new HttpClientTransport(this._httpClient) + }); + builder.Services.AddSingleton(client); this._kernel = builder.Build(); } diff --git a/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs b/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs index dd464faf189d..016ca6148596 100644 --- a/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs +++ b/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs @@ -7,7 +7,7 @@ using System.Text; using System.Text.Json; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Core.Pipeline; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; @@ -38,12 +38,14 @@ public AzureAIKernelAgentYamlTests() var builder = Kernel.CreateBuilder(); // Add Azure AI agents client - var client = new AIProjectClient( - "endpoint;subscription_id;resource_group_name;project_name", + var client = new PersistentAgentsClient( + new Uri("https://test"), new FakeTokenCredential(), - new AIProjectClientOptions() - { Transport = new HttpClientTransport(this._httpClient) }); - builder.Services.AddSingleton(client); + new PersistentAgentsClientOptions + { + Transport = new HttpClientTransport(this._httpClient) + }); + builder.Services.AddSingleton(client); this._kernel = builder.Build(); this._kernel.Plugins.Add(KernelPluginFactory.CreateFromType()); diff --git a/dotnet/src/IntegrationTests/Agents/MixedAgentTests.cs b/dotnet/src/IntegrationTests/Agents/MixedAgentTests.cs index dd39b660966d..7ec24fbecf4e 100644 --- a/dotnet/src/IntegrationTests/Agents/MixedAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/MixedAgentTests.cs @@ -12,6 +12,7 @@ using Microsoft.SemanticKernel.Agents.OpenAI; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.OpenAI; +using OpenAI; using OpenAI.Assistants; using SemanticKernel.IntegrationTests.TestSettings; using xRetry; @@ -45,7 +46,7 @@ public async Task OpenAIMixedAgentTestAsync(bool useNewFunctionCallingModel) // Arrange, Act & Assert await this.VerifyAgentExecutionAsync( this.CreateChatCompletionKernel(openAISettings), - OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(openAISettings.ApiKey)), + OpenAIAssistantAgent.CreateOpenAIClient(new ApiKeyCredential(openAISettings.ApiKey)), openAISettings.ChatModelId!, useNewFunctionCallingModel); } @@ -65,14 +66,14 @@ public async Task AzureOpenAIMixedAgentAsync(bool useNewFunctionCallingModel) // Arrange, Act & Assert await this.VerifyAgentExecutionAsync( this.CreateChatCompletionKernel(azureOpenAISettings), - OpenAIClientProvider.ForAzureOpenAI(new AzureCliCredential(), new Uri(azureOpenAISettings.Endpoint)), + OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(azureOpenAISettings.Endpoint)), azureOpenAISettings.ChatDeploymentName!, useNewFunctionCallingModel); } private async Task VerifyAgentExecutionAsync( Kernel chatCompletionKernel, - OpenAIClientProvider clientProvider, + OpenAIClient client, string modelName, bool useNewFunctionCallingModel) { @@ -95,8 +96,9 @@ private async Task VerifyAgentExecutionAsync( chatAgent.Kernel.Plugins.Add(plugin); // Configure assistant agent with the plugin. - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); - OpenAIAssistantAgent assistantAgent = new(definition, clientProvider.AssistantClient, [plugin]); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); + OpenAIAssistantAgent assistantAgent = new(definition, assistantClient, [plugin]); // Act & Assert try @@ -107,7 +109,7 @@ private async Task VerifyAgentExecutionAsync( } finally { - await clientProvider.AssistantClient.DeleteAssistantAsync(assistantAgent.Id); + await assistantClient.DeleteAssistantAsync(assistantAgent.Id); } } diff --git a/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs b/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs index 35496121715e..428765d243f7 100644 --- a/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs @@ -14,6 +14,7 @@ using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.OpenAI; using Microsoft.SemanticKernel.ChatCompletion; +using OpenAI; using OpenAI.Assistants; using OpenAI.Files; using OpenAI.VectorStores; @@ -46,7 +47,7 @@ public async Task OpenAIAssistantAgentTestAsync(string input, string expectedAns Assert.NotNull(openAISettings); await this.ExecuteAgentAsync( - OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(openAISettings.ApiKey)), + OpenAIAssistantAgent.CreateOpenAIClient(new ApiKeyCredential(openAISettings.ApiKey)), openAISettings.ChatModelId!, input, expectedAnswerContains); @@ -63,8 +64,11 @@ public async Task AzureOpenAIAssistantAgentAsync(string input, string expectedAn var azureOpenAIConfiguration = this._configuration.GetSection("AzureOpenAI").Get(); Assert.NotNull(azureOpenAIConfiguration); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + await this.ExecuteAgentAsync( - OpenAIClientProvider.ForAzureOpenAI(new AzureCliCredential(), new Uri(azureOpenAIConfiguration.Endpoint)), + CreateClient(azureOpenAIConfiguration), azureOpenAIConfiguration.ChatDeploymentName!, input, expectedAnswerContains); @@ -82,7 +86,7 @@ public async Task OpenAIAssistantAgentStreamingAsync(string input, string expect Assert.NotNull(openAISettings); await this.ExecuteStreamingAgentAsync( - OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(openAISettings.ApiKey)), + OpenAIAssistantAgent.CreateOpenAIClient(new ApiKeyCredential(openAISettings.ApiKey)), openAISettings.ModelId, input, expectedAnswerContains); @@ -99,7 +103,7 @@ public async Task AzureOpenAIAssistantAgentStreamingAsync(string input, string e AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); await this.ExecuteStreamingAgentAsync( - CreateClientProvider(azureOpenAIConfiguration), + CreateClient(azureOpenAIConfiguration), azureOpenAIConfiguration.ChatDeploymentName!, input, expectedAnswerContains); @@ -114,11 +118,12 @@ await this.ExecuteStreamingAgentAsync( public async Task AzureOpenAIAssistantAgentFunctionCallResultAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); + OpenAIAssistantAgent agent = new(definition, assistantClient); - AssistantThread thread = await clientProvider.AssistantClient.CreateThreadAsync(); + AssistantThread thread = await assistantClient.CreateThreadAsync(); ChatMessageContent functionResultMessage = new(AuthorRole.Assistant, [new FunctionResultContent("mock-function", result: "A result value")]); try { @@ -128,8 +133,8 @@ public async Task AzureOpenAIAssistantAgentFunctionCallResultAsync() } finally { - await clientProvider.AssistantClient.DeleteThreadAsync(thread.Id); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteThreadAsync(thread.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } @@ -142,9 +147,10 @@ public async Task AzureOpenAIAssistantAgentFunctionCallResultAsync() public async Task AzureOpenAIAssistantAgentTokensAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!, instructions: "Repeat the user all of the user messages"); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient) + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!, instructions: "Repeat the user all of the user messages"); + OpenAIAssistantAgent agent = new(definition, assistantClient) { RunOptions = new() { @@ -152,7 +158,7 @@ public async Task AzureOpenAIAssistantAgentTokensAsync() } }; - AssistantThread thread = await clientProvider.AssistantClient.CreateThreadAsync(); + AssistantThread thread = await assistantClient.CreateThreadAsync(); ChatMessageContent functionResultMessage = new(AuthorRole.User, "A long time ago there lived a king who was famed for his wisdom through all the land. Nothing was hidden from him, and it seemed as if news of the most secret things was brought to him through the air. But he had a strange custom; every day after dinner, when the table was cleared, and no one else was present, a trusty servant had to bring him one more dish. It was covered, however, and even the servant did not know what was in it, neither did anyone know, for the king never took off the cover to eat of it until he was quite alone."); try { @@ -161,8 +167,8 @@ public async Task AzureOpenAIAssistantAgentTokensAsync() } finally { - await clientProvider.AssistantClient.DeleteThreadAsync(thread.Id); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteThreadAsync(thread.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } @@ -173,9 +179,10 @@ public async Task AzureOpenAIAssistantAgentTokensAsync() public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); + OpenAIAssistantAgent agent = new(definition, assistantClient); ThreadCreationOptions threadOptions = new() { @@ -185,7 +192,7 @@ public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsAsync() new ChatMessageContent(AuthorRole.User, "How may I help you?").ToThreadInitializationMessage(), } }; - OpenAIAssistantAgentThread agentThread = new(clientProvider.AssistantClient, threadOptions); + OpenAIAssistantAgentThread agentThread = new(assistantClient, threadOptions); try { @@ -211,7 +218,7 @@ public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsAsync() finally { await agentThread.DeleteAsync(); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } @@ -224,9 +231,10 @@ public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsAsync() public async Task AzureOpenAIAssistantAgentAdditionalMessagesAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); + OpenAIAssistantAgent agent = new(definition, assistantClient); ThreadCreationOptions threadOptions = new() { @@ -236,7 +244,7 @@ public async Task AzureOpenAIAssistantAgentAdditionalMessagesAsync() new ChatMessageContent(AuthorRole.User, "How may I help you?").ToThreadInitializationMessage(), } }; - AssistantThread thread = await clientProvider.AssistantClient.CreateThreadAsync(threadOptions); + AssistantThread thread = await assistantClient.CreateThreadAsync(threadOptions); try { var messages = await agent.GetThreadMessagesAsync(thread.Id).ToArrayAsync(); @@ -260,8 +268,8 @@ public async Task AzureOpenAIAssistantAgentAdditionalMessagesAsync() } finally { - await clientProvider.AssistantClient.DeleteThreadAsync(thread.Id); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteThreadAsync(thread.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } @@ -274,17 +282,18 @@ public async Task AzureOpenAIAssistantAgentAdditionalMessagesAsync() public async Task AzureOpenAIAssistantAgentStreamingFileSearchAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); + OpenAIAssistantAgent agent = new(definition, assistantClient); // Upload file - Using a table of fictional employees. - OpenAIFileClient fileClient = clientProvider.Client.GetOpenAIFileClient(); + OpenAIFileClient fileClient = client.GetOpenAIFileClient(); await using Stream stream = File.OpenRead("TestData/employees.pdf")!; OpenAIFile fileInfo = await fileClient.UploadFileAsync(stream, "employees.pdf", FileUploadPurpose.Assistants); // Create a vector-store - VectorStoreClient vectorStoreClient = clientProvider.Client.GetVectorStoreClient(); + VectorStoreClient vectorStoreClient = client.GetVectorStoreClient(); CreateVectorStoreOperation result = await vectorStoreClient.CreateVectorStoreAsync(waitUntilCompleted: false, new VectorStoreCreationOptions() @@ -292,7 +301,7 @@ await vectorStoreClient.CreateVectorStoreAsync(waitUntilCompleted: false, FileIds = { fileInfo.Id } }); - AssistantThread thread = await clientProvider.AssistantClient.CreateThreadAsync(); + AssistantThread thread = await assistantClient.CreateThreadAsync(); try { await agent.AddChatMessageAsync(thread.Id, new(AuthorRole.User, "Who works in sales?")); @@ -303,8 +312,8 @@ await vectorStoreClient.CreateVectorStoreAsync(waitUntilCompleted: false, } finally { - await clientProvider.AssistantClient.DeleteThreadAsync(thread.Id); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteThreadAsync(thread.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); await vectorStoreClient.DeleteVectorStoreAsync(result.VectorStoreId); await fileClient.DeleteFileAsync(fileInfo.Id); } @@ -317,11 +326,12 @@ await vectorStoreClient.CreateVectorStoreAsync(waitUntilCompleted: false, public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsStreamingAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(azureOpenAIConfiguration.ChatDeploymentName!); + OpenAIAssistantAgent agent = new(definition, assistantClient); - OpenAIAssistantAgentThread agentThread = new(clientProvider.AssistantClient); + OpenAIAssistantAgentThread agentThread = new(assistantClient); try { @@ -342,7 +352,7 @@ public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsStreamingAsync finally { await agentThread.DeleteAsync(); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } @@ -353,7 +363,8 @@ public async Task AzureOpenAIAssistantAgentWithThreadCustomOptionsStreamingAsync public async Task AzureOpenAIAssistantAgentDeclarativeAsync() { AzureOpenAIConfiguration azureOpenAIConfiguration = this.ReadAzureConfiguration(); - OpenAIClientProvider clientProvider = CreateClientProvider(azureOpenAIConfiguration); + OpenAIClient client = CreateClient(azureOpenAIConfiguration); + AssistantClient assistantClient = client.GetAssistantClient(); var text = $""" @@ -376,7 +387,7 @@ public async Task AzureOpenAIAssistantAgentDeclarativeAsync() var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = kernel }); Assert.NotNull(agent); - OpenAIAssistantAgentThread agentThread = new(clientProvider.AssistantClient); + OpenAIAssistantAgentThread agentThread = new(assistantClient); try { RunCreationOptions invocationOptions = new() @@ -394,22 +405,22 @@ public async Task AzureOpenAIAssistantAgentDeclarativeAsync() finally { await agentThread.DeleteAsync(); - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } private async Task ExecuteAgentAsync( - OpenAIClientProvider clientProvider, + OpenAIClient client, string modelName, string input, string expected) { // Arrange Kernel kernel = new(); - KernelPlugin plugin = KernelPluginFactory.CreateFromType(); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient, [plugin]); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await client.GetAssistantClient().CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); + OpenAIAssistantAgent agent = new(definition, assistantClient, [plugin]); try { @@ -432,12 +443,12 @@ private async Task ExecuteAgentAsync( } finally { - await clientProvider.AssistantClient.DeleteAssistantAsync(agent.Id); + await assistantClient.DeleteAssistantAsync(agent.Id); } } private async Task ExecuteStreamingAgentAsync( - OpenAIClientProvider clientProvider, + OpenAIClient client, string modelName, string input, string expected) @@ -446,8 +457,9 @@ private async Task ExecuteStreamingAgentAsync( Kernel kernel = new(); KernelPlugin plugin = KernelPluginFactory.CreateFromType(); - Assistant definition = await clientProvider.AssistantClient.CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); - OpenAIAssistantAgent agent = new(definition, clientProvider.AssistantClient, [plugin]); + AssistantClient assistantClient = client.GetAssistantClient(); + Assistant definition = await assistantClient.CreateAssistantAsync(modelName, instructions: "Answer questions about the menu."); + OpenAIAssistantAgent agent = new(definition, assistantClient, [plugin]); AgentGroupChat chat = new(); chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input)); @@ -489,9 +501,9 @@ private AzureOpenAIConfiguration ReadAzureConfiguration() return azureOpenAIConfiguration; } - private static OpenAIClientProvider CreateClientProvider(AzureOpenAIConfiguration azureOpenAIConfiguration) + private static OpenAIClient CreateClient(AzureOpenAIConfiguration azureOpenAIConfiguration) { - return OpenAIClientProvider.ForAzureOpenAI(new AzureCliCredential(), new Uri(azureOpenAIConfiguration.Endpoint)); + return OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(azureOpenAIConfiguration.Endpoint)); } public sealed class MenuPlugin diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAgentsTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAgentsTest.cs index 29b87d49105d..5020c51322b8 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAgentsTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAgentsTest.cs @@ -2,7 +2,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.OpenAI; diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureAgentTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureAgentTest.cs index a36932db1f38..282e39fa7312 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureAgentTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureAgentTest.cs @@ -1,13 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. -using System.ClientModel; using System.Collections.ObjectModel; using System.Diagnostics; -using Azure.AI.Projects; -using Azure.Identity; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; -using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.Agents.OpenAI; using Microsoft.SemanticKernel.ChatCompletion; using OpenAI.Assistants; @@ -41,27 +38,6 @@ public abstract class BaseAzureTest(ITestOutputHelper output) : BaseTest(output, { AssistantSampleMetadataKey, bool.TrueString } }); - /// - /// Provide a according to the configuration settings. - /// - protected AzureAIClientProvider GetAzureProvider() - { - return AzureAIClientProvider.FromConnectionString(TestConfiguration.AzureAI.ConnectionString, new AzureCliCredential()); - } - - /// - /// Provide a according to the configuration settings. - /// - protected OpenAIClientProvider GetClientProvider() - { - return - this.UseOpenAIConfig ? - OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(this.ApiKey ?? throw new ConfigurationNotFoundException("OpenAI:ApiKey"))) : - !string.IsNullOrWhiteSpace(this.ApiKey) ? - OpenAIClientProvider.ForAzureOpenAI(new ApiKeyCredential(this.ApiKey), new Uri(this.Endpoint!)) : - OpenAIClientProvider.ForAzureOpenAI(new AzureCliCredential(), new Uri(this.Endpoint!)); - } - /// /// Common method to write formatted agent chat content to the console. /// diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs index e0c937870e54..0068a600f17f 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. using System.Diagnostics; +using Azure; +using Azure.AI.Agents.Persistent; using Azure.AI.Projects; using Azure.Identity; using Microsoft.SemanticKernel; @@ -10,16 +12,18 @@ /// /// Base class for samples that demonstrate the usage of . /// -public abstract class BaseAzureAgentTest : BaseAgentsTest +public abstract class BaseAzureAgentTest : BaseAgentsTest { protected BaseAzureAgentTest(ITestOutputHelper output) : base(output) { - this.Client = AzureAIAgent.CreateAzureAIClient(TestConfiguration.AzureAI.ConnectionString, new AzureCliCredential()); - this.AgentsClient = this.Client.GetAgentsClient(); + this.Client = + string.IsNullOrEmpty(TestConfiguration.AzureAI.ApiKey) ? + AzureAIAgent.CreateAgentsClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureCliCredential()) : + AzureAIAgent.CreateAgentsClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureKeyCredential(TestConfiguration.AzureAI.ApiKey)); } /// - protected override AIProjectClient Client { get; } + protected override PersistentAgentsClient Client { get; } /// /// Gets the . @@ -39,8 +43,8 @@ protected async Task DownloadContentAsync(ChatMessageContent message) protected async Task DownloadFileAsync(string fileId, bool launchViewer = false) { - AgentFile fileInfo = this.AgentsClient.GetFile(fileId); - if (fileInfo.Purpose == AgentFilePurpose.AgentsOutput) + PersistentAgentFile fileInfo = this.Client.GetFile(fileId); + if (fileInfo.Purpose == PersistentAgentFilePurpose.AgentsOutput) { string filePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(fileInfo.Filename)); if (launchViewer) @@ -48,7 +52,7 @@ protected async Task DownloadFileAsync(string fileId, bool launchViewer = false) filePath = Path.ChangeExtension(filePath, ".png"); } - BinaryData content = await this.AgentsClient.GetFileContentAsync(fileId); + BinaryData content = await this.Client.GetFileContentAsync(fileId); File.WriteAllBytes(filePath, content.ToArray()); Console.WriteLine($" File #{fileId} saved to: {filePath}"); diff --git a/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs b/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs index e140e9b17a10..76e5b7628612 100644 --- a/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs +++ b/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs @@ -105,7 +105,8 @@ public class OnnxConfig public class AzureAIConfig { - public string ConnectionString { get; set; } + public string Endpoint { get; set; } + public string? ApiKey { get; set; } public string ChatModelId { get; set; } public string BingConnectionId { get; set; } public string VectorStoreId { get; set; } From 7a10397fb8280a5ec0aa36c3a6d9e91518714aa4 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 16:39:11 -0700 Subject: [PATCH 02/20] Fix test --- .../AzureAIAgent/Step08_AzureAIAgent_Declarative.cs | 5 ++++- dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs | 7 +++---- .../IntegrationTests/Agents/OpenAIAssistantAgentTests.cs | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index d47a83ded3a6..cd520a176328 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -36,6 +36,7 @@ public async Task AzureAIAgentWithConfiguration() AzureAIAgentFactory factory = new(); var builder = Kernel.CreateBuilder(); + builder.Services.AddSingleton(this.Client); builder.Services.AddSingleton(new AzureCliCredential()); var kernel = builder.Build(); @@ -53,6 +54,8 @@ public async Task AzureAIAgentWithKernel() name: MyAgent description: My helpful agent. instructions: You are helpful agent. + model: + id: ${AzureOpenAI:ChatModelId} """; AzureAIAgentFactory factory = new(); @@ -416,7 +419,7 @@ public async Task AzureAIAgentWithTemplate() public Step08_AzureAIAgent_Declarative(ITestOutputHelper output) : base(output) { var builder = Kernel.CreateBuilder(); - builder.Services.AddSingleton(this.Client); + builder.Services.AddSingleton(this.Client); this._kernel = builder.Build(); } diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs index eb83d3529ab5..72fed94725c8 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs @@ -3,7 +3,6 @@ using System.Net.Http; using Azure; using Azure.AI.Agents.Persistent; -using Azure.AI.Projects.OneDP; using Azure.Core; using Azure.Core.Pipeline; using Microsoft.SemanticKernel.Http; @@ -11,12 +10,12 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// -/// Provides an for use by . +/// Provides an for use by . /// public sealed partial class AzureAIAgent : Agent { /// - /// Produces a . + /// Produces a . /// /// The Azure AI Foundry project endpoint. /// A credential used to authenticate to an Azure Service. @@ -35,7 +34,7 @@ public static PersistentAgentsClient CreateAgentsClient( } /// - /// Produces a . + /// Produces a . /// /// The Azure AI Foundry project endpoint. /// A credential used to authenticate to an Azure Service. diff --git a/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs b/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs index 428765d243f7..7cef37d82cea 100644 --- a/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/OpenAIAssistantAgentTests.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Azure.AI.OpenAI; using Azure.Core; using Azure.Identity; using Microsoft.Extensions.Configuration; @@ -501,7 +502,7 @@ private AzureOpenAIConfiguration ReadAzureConfiguration() return azureOpenAIConfiguration; } - private static OpenAIClient CreateClient(AzureOpenAIConfiguration azureOpenAIConfiguration) + private static AzureOpenAIClient CreateClient(AzureOpenAIConfiguration azureOpenAIConfiguration) { return OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(azureOpenAIConfiguration.Endpoint)); } From 406218adb483e0d3d91ba7cec1392cb637d473e6 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 16:50:21 -0700 Subject: [PATCH 03/20] Namespace --- .../AzureAIAgent/Step08_AzureAIAgent_Declarative.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index cd520a176328..d47d1c7e901a 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -1,5 +1,4 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Agents.Persistent; using Azure.Core; using Azure.Identity; using Microsoft.Extensions.DependencyInjection; From 98705c22bf90f1e6562ef95221f8781f78c508f3 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 16:53:05 -0700 Subject: [PATCH 04/20] Namespace --- dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs index 6f1e9645ed8f..4e75b636ff0d 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Azure; -using Azure.AI.Projects; using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; From 6475fdd2d77a84bce9703bc43bf53dd3f8cb5e1f Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 16:58:05 -0700 Subject: [PATCH 05/20] Namespace --- dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs b/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs index c84265f70f63..fa62275d0d25 100644 --- a/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs +++ b/dotnet/src/Agents/OpenAI/Extensions/AgentDefinitionExtensions.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; -using Azure.AI.OpenAI; using Azure.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel.Http; From e920a2859f92a84c3473e551541b7a24c1f733dc Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 17:05:09 -0700 Subject: [PATCH 06/20] Namespace --- .../UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs index 5b46b241d65a..0ef4043e26e4 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs @@ -5,7 +5,6 @@ using System.Net.Http; using System.Threading.Tasks; using Azure.AI.Agents.Persistent; -using Azure.AI.Projects.OneDP; using Azure.Core.Pipeline; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; From 6b531012fb7aea060cbe461905b6bbf4705aa28e Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 17:16:09 -0700 Subject: [PATCH 07/20] Concepts --- .../Agents/AzureAIAgent_FileManipulation.cs | 15 +++++++------ .../Concepts/Agents/AzureAIAgent_Streaming.cs | 21 +++++++++---------- dotnet/src/Agents/AzureAI/AzureAIAgent.cs | 2 +- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs index 120af824229c..6d7ebcbb557a 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs @@ -1,10 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; using Resources; -using Agent = Azure.AI.Projects.Agent; namespace Agents; @@ -17,10 +16,10 @@ public class AzureAIAgent_FileManipulation(ITestOutputHelper output) : BaseAzure public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() { await using Stream stream = EmbeddedResource.ReadStream("sales.csv")!; - AgentFile fileInfo = await this.AgentsClient.UploadFileAsync(stream, AgentFilePurpose.Agents, "sales.csv"); + PersistentAgentFile fileInfo = await this.Client.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "sales.csv"); // Define the agent - Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new CodeInterpreterToolDefinition()], toolResources: @@ -31,8 +30,8 @@ public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() FileIds = { fileInfo.Id }, } }); - AzureAIAgent agent = new(definition, this.AgentsClient); - AzureAIAgentThread thread = new(this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); + AzureAIAgentThread thread = new(this.Client); // Respond to user input try @@ -44,8 +43,8 @@ public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); - await this.AgentsClient.DeleteFileAsync(fileInfo.Id); + await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.DeleteFileAsync(fileInfo.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs index d03b223c1cd3..ec834b3b2e19 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. using System.ComponentModel; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; -using Agent = Azure.AI.Projects.Agent; namespace Agents; @@ -21,15 +20,15 @@ public async Task UseStreamingAgentAsync() const string AgentInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound."; // Define the agent - Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, AgentInstructions); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - AzureAIAgentThread agentThread = new(this.AgentsClient, metadata: SampleMetadata); + AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); // Respond to user input await InvokeAgentAsync(agent, agentThread, "Fortune favors the bold."); @@ -47,19 +46,19 @@ public async Task UseStreamingAssistantAgentWithPluginAsync() const string AgentInstructions = "Answer questions about the menu."; // Define the agent - Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, AgentInstructions); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Initialize plugin and add to the agent's Kernel (same as direct Kernel usage). KernelPlugin plugin = KernelPluginFactory.CreateFromType(); agent.Kernel.Plugins.Add(plugin); // Create a thread for the agent conversation. - AzureAIAgentThread agentThread = new(this.AgentsClient, metadata: SampleMetadata); + AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); // Respond to user input await InvokeAgentAsync(agent, agentThread, "What is the special soup and its price?"); @@ -76,16 +75,16 @@ public async Task UseStreamingAssistantWithCodeInterpreterAsync() const string AgentInstructions = "Solve math problems with code."; // Define the agent - Agent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, AgentInstructions, [new CodeInterpreterToolDefinition()]); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - AzureAIAgentThread agentThread = new(this.AgentsClient, metadata: SampleMetadata); + AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); // Respond to user input await InvokeAgentAsync(agent, agentThread, "Is 191 a prime number?"); diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs index 1b4f9a7542da..bc040335c9c7 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs @@ -55,7 +55,7 @@ public static class Tools /// Initializes a new instance of the class. /// /// The agent model definition. - /// An instance. + /// An instance. /// Optional collection of plugins to add to the kernel. /// An optional factory to produce the for the agent. /// The format of the prompt template used when "templateFactory" parameter is supplied. From bf7e65d08eb918e7d3dfbcc11a2e20a43599945b Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Mon, 12 May 2025 17:31:03 -0700 Subject: [PATCH 08/20] Stragglers --- .../Samples/AzureAIAgentWithMCPToolsSample.cs | 10 +++---- .../Agents/AzureAIAgentTests.cs | 30 +++++++++---------- .../AzureAIAgentFixture.cs | 18 +++++------ 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs b/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs index 843fa00cba9c..9edc49ef9bfb 100644 --- a/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs +++ b/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Azure.Identity; using Microsoft.Extensions.Configuration; using Microsoft.SemanticKernel; @@ -86,7 +86,7 @@ private static async Task CreateAzureAIAgentAsync(Kernel kernel, s .AddEnvironmentVariables() .Build(); - if (config["AzureAI:ConnectionString"] is not { } connectionString) + if (config["AzureAI:Endpoint"] is not { } endpoint) { const string Message = "Please provide a valid `AzureAI:ConnectionString` secret to run this sample. See the associated README.md for more details."; Console.Error.WriteLine(Message); @@ -96,11 +96,9 @@ private static async Task CreateAzureAIAgentAsync(Kernel kernel, s string modelId = config["AzureAI:ChatModelId"] ?? "gpt-4o-mini"; // Create the Azure AI Agent - AIProjectClient projectClient = AzureAIAgent.CreateAzureAIClient(connectionString, new AzureCliCredential()); + PersistentAgentsClient agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(endpoint), new AzureCliCredential()); - AgentsClient agentsClient = projectClient.GetAgentsClient(); - - Azure.AI.Projects.Agent agent = await agentsClient.CreateAgentAsync(modelId, name, null, instructions); + PersistentAgent agent = await agentsClient.CreateAgentAsync(modelId, name, null, instructions); return new AzureAIAgent(agent, agentsClient) { diff --git a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs index df336f5f62e2..4b4e0c49009e 100644 --- a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Linq; using System.Threading.Tasks; +using Azure.AI.Agents.Persistent; using Azure.AI.Projects; using Azure.Identity; using Microsoft.Extensions.Configuration; @@ -21,16 +23,14 @@ public class AzureAIAgentTests { private readonly Kernel _kernel; private readonly AzureAIConfiguration _configuration; - private readonly AIProjectClient _client; - private readonly AgentsClient _agentsClient; + private readonly PersistentAgentsClient _client; public AzureAIAgentTests() { var kernelBuilder = Kernel.CreateBuilder(); this._kernel = kernelBuilder.Build(); this._configuration = this.ReadAzureConfiguration(); - this._client = AzureAIAgent.CreateAzureAIClient(this._configuration.ConnectionString!, new AzureCliCredential()); - this._agentsClient = this._client.GetAgentsClient(); + this._client = AzureAIAgent.CreateAgentsClient(new Uri(this._configuration.Endpoint), new AzureCliCredential()); } /// @@ -40,14 +40,14 @@ public AzureAIAgentTests() public async Task AzureAIAgentWithThreadCustomOptionsAsync() { var aiAgent = - await this._agentsClient.CreateAgentAsync( + await this._client.CreateAgentAsync( this._configuration.ChatModelId, name: "HelpfulAssistant", description: "Helpful Assistant", instructions: "You are a helpful assistant."); - var agent = new AzureAIAgent(aiAgent, this._agentsClient) { Kernel = this._kernel }; + var agent = new AzureAIAgent(aiAgent, this._client) { Kernel = this._kernel }; - AzureAIAgentThread agentThread = new(this._agentsClient); + AzureAIAgentThread agentThread = new(this._client); try { @@ -63,7 +63,7 @@ await this._agentsClient.CreateAgentAsync( finally { await agentThread.DeleteAsync(); - await this._agentsClient.DeleteAgentAsync(agent.Id); + await this._client.DeleteAgentAsync(agent.Id); } } @@ -74,14 +74,14 @@ await this._agentsClient.CreateAgentAsync( public async Task AzureAIAgentWithThreadCustomOptionsStreamingAsync() { var aiAgent = - await this._agentsClient.CreateAgentAsync( + await this._client.CreateAgentAsync( this._configuration.ChatModelId, name: "HelpfulAssistant", description: "Helpful Assistant", instructions: "You are a helpful assistant."); - var agent = new AzureAIAgent(aiAgent, this._agentsClient) { Kernel = this._kernel }; + var agent = new AzureAIAgent(aiAgent, this._client) { Kernel = this._kernel }; - AzureAIAgentThread agentThread = new(this._agentsClient); + AzureAIAgentThread agentThread = new(this._client); try { @@ -97,7 +97,7 @@ await this._agentsClient.CreateAgentAsync( finally { await agentThread.DeleteAsync(); - await this._agentsClient.DeleteAgentAsync(agent.Id); + await this._client.DeleteAgentAsync(agent.Id); } } @@ -108,7 +108,7 @@ await this._agentsClient.CreateAgentAsync( public async Task AzureAIAgentDeclarativeAsync() { var builder = Kernel.CreateBuilder(); - builder.Services.AddSingleton(this._client); + builder.Services.AddSingleton(this._client); var kernel = builder.Build(); var text = @@ -125,7 +125,7 @@ public async Task AzureAIAgentDeclarativeAsync() var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = kernel }); Assert.NotNull(agent); - AzureAIAgentThread agentThread = new(this._agentsClient); + AzureAIAgentThread agentThread = new(this._client); try { var response = await agent.InvokeAsync("What is the capital of France?", agentThread).FirstAsync(); @@ -135,7 +135,7 @@ public async Task AzureAIAgentDeclarativeAsync() finally { await agentThread.DeleteAsync(); - await this._agentsClient.DeleteAgentAsync(agent.Id); + await this._client.DeleteAgentAsync(agent.Id); } } diff --git a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs index 769e3daec9d7..64db43c3d6c4 100644 --- a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs +++ b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Threading.Tasks; using Azure; +using Azure.AI.Agents.Persistent; using Azure.Identity; using Microsoft.Extensions.Configuration; using Microsoft.SemanticKernel; @@ -9,7 +11,6 @@ using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; using SemanticKernel.IntegrationTests.TestSettings; -using AAIP = Azure.AI.Projects; namespace SemanticKernel.IntegrationTests.Agents.CommonInterfaceConformance; @@ -22,8 +23,8 @@ public class AzureAIAgentFixture : AgentFixture .AddUserSecrets() .Build(); - private AAIP.AgentsClient? _agentsClient; - private AAIP.Agent? _aiAgent; + private PersistentAgentsClient? _agentsClient; + private PersistentAgent? _aiAgent; private AzureAIAgent? _agent; private AzureAIAgentThread? _thread; private AzureAIAgentThread? _createdThread; @@ -43,7 +44,7 @@ public class AzureAIAgentFixture : AgentFixture public override async Task GetChatHistory() { var chatHistory = new ChatHistory(); - await foreach (var existingMessage in this._thread!.GetMessagesAsync(AAIP.ListSortOrder.Ascending).ConfigureAwait(false)) + await foreach (var existingMessage in this._thread!.GetMessagesAsync(ListSortOrder.Ascending).ConfigureAwait(false)) { chatHistory.Add(existingMessage); } @@ -90,8 +91,7 @@ public override async Task DisposeAsync() public override async Task InitializeAsync() { AzureAIConfiguration configuration = this._configuration.GetSection("AzureAI").Get()!; - var client = AzureAIAgent.CreateAzureAIClient(configuration.ConnectionString!, new AzureCliCredential()); - this._agentsClient = client.GetAgentsClient(); + this._agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(configuration.Endpoint), new AzureCliCredential()); this._aiAgent = await this._agentsClient.CreateAgentAsync( @@ -109,10 +109,10 @@ await this._agentsClient.CreateAgentAsync( this._createdThread = new AzureAIAgentThread(this._agentsClient); await this._createdThread.CreateAsync(); - var serviceFailingClient = AzureAIAgent.CreateAzureAIClient("swedencentral.api.azureml.ms;;;", new AzureCliCredential()); - this._serviceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient.GetAgentsClient()); + var serviceFailingClient = AzureAIAgent.CreateAgentsClient(new Uri("https://invalid"), new AzureCliCredential()); + this._serviceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient); var createdFailingThreadResponse = await this._agentsClient.CreateThreadAsync(); - this._createdServiceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient.GetAgentsClient(), createdFailingThreadResponse.Value.Id); + this._createdServiceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient, createdFailingThreadResponse.Value.Id); } } From 53009d5db3e5c6691e67cf8ab7d3876dc02dcfd2 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Tue, 13 May 2025 15:48:14 -0700 Subject: [PATCH 09/20] Merge and resolve --- .../Step09_AzureAIAgent_BingGrounding.cs | 34 ++++++++++--------- .../samples/AgentUtilities/BaseAzureTest.cs | 11 +++--- .../Contents/StreamingAnnotationContent.cs | 8 ++--- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs index 71eaae05575a..44a21f3094ce 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft. All rights reserved. -using Azure.AI.Projects; +using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; -using FoundryAgent = Azure.AI.Projects.Agent; +using AAIP = Azure.AI.Projects.OneDP; namespace GettingStarted.AzureAgents; @@ -17,21 +17,22 @@ public class Step09_AzureAIAgent_BingGrounding(ITestOutputHelper output) : BaseA public async Task UseBingGroundingToolWithAgent() { // Access the BingGrounding connection - ConnectionsClient connectionsClient = this.Client.GetConnectionsClient(); - ConnectionResponse bingConnection = await connectionsClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); + AAIP.AIProjectClient projectClient = this.CreateProjectClient(); + AAIP.Connections connectionsClient = projectClient.GetConnectionsClient(); + AAIP.Connection bingConnectionResponse = await connectionsClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); // Define the agent ToolConnectionList toolConnections = new() { - ConnectionList = { new ToolConnection(bingConnection.Id) } + ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } }; - FoundryAgent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new BingGroundingToolDefinition(toolConnections)]); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - AzureAIAgentThread thread = new(this.AgentsClient, metadata: SampleMetadata); + AzureAIAgentThread thread = new(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -42,7 +43,7 @@ public async Task UseBingGroundingToolWithAgent() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. @@ -62,21 +63,22 @@ async Task InvokeAgentAsync(string input) public async Task UseBingGroundingToolWithStreaming() { // Access the BingGrounding connection - ConnectionsClient connectionClient = this.Client.GetConnectionsClient(); - ConnectionResponse bingConnectionResponse = await connectionClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); + AAIP.AIProjectClient projectClient = this.CreateProjectClient(); + AAIP.Connections connectionsClient = projectClient.GetConnectionsClient(); + AAIP.Connection bingConnectionResponse = await connectionsClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); // Define the agent ToolConnectionList toolConnections = new() { - ConnectionList = { new ToolConnection(bingConnectionResponse.Id) } + ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } }; - FoundryAgent definition = await this.AgentsClient.CreateAgentAsync( + PersistentAgent definition = await this.Client.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new BingGroundingToolDefinition(toolConnections)]); - AzureAIAgent agent = new(definition, this.AgentsClient); + AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. - AzureAIAgentThread thread = new(this.AgentsClient, metadata: SampleMetadata); + AzureAIAgentThread thread = new(this.Client, metadata: SampleMetadata); // Respond to user input try @@ -96,7 +98,7 @@ public async Task UseBingGroundingToolWithStreaming() finally { await thread.DeleteAsync(); - await this.AgentsClient.DeleteAgentAsync(agent.Id); + await this.Client.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs index 389195149c79..36f084831393 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using Azure; using Azure.AI.Agents.Persistent; -using Azure.AI.Projects; +using Azure.AI.Projects.OneDP; using Azure.Identity; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; @@ -22,13 +22,12 @@ protected BaseAzureAgentTest(ITestOutputHelper output) : base(output) AzureAIAgent.CreateAgentsClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureKeyCredential(TestConfiguration.AzureAI.ApiKey)); } - /// protected override PersistentAgentsClient Client { get; } - /// - /// Gets the . - /// - protected AgentsClient AgentsClient { get; } + protected AIProjectClient CreateProjectClient() => + string.IsNullOrEmpty(TestConfiguration.AzureAI.ApiKey) ? + new AIProjectClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureCliCredential()) : + new AIProjectClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureKeyCredential(TestConfiguration.AzureAI.ApiKey)); protected async Task DownloadContentAsync(ChatMessageContent message) { diff --git a/dotnet/src/SemanticKernel.Abstractions/Contents/StreamingAnnotationContent.cs b/dotnet/src/SemanticKernel.Abstractions/Contents/StreamingAnnotationContent.cs index 60b2145d907d..c6e339f7e864 100644 --- a/dotnet/src/SemanticKernel.Abstractions/Contents/StreamingAnnotationContent.cs +++ b/dotnet/src/SemanticKernel.Abstractions/Contents/StreamingAnnotationContent.cs @@ -24,7 +24,6 @@ public class StreamingAnnotationContent : StreamingKernelContent public string FileId { get => this.ReferenceId; - init => this.ReferenceId = value; } /// @@ -40,11 +39,12 @@ public string FileId /// /// Provides context for using . /// - public AnnotationKind Kind { get; init; } + public AnnotationKind Kind { get; } /// /// The citation. /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Label { get; init; } /// @@ -54,8 +54,7 @@ public string FileId /// A file is referenced for certain tools, such as file search, and also when /// and image or document is produced as part of the agent response. /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string ReferenceId { get; init; } + public string ReferenceId { get; } /// /// The title of the annotation reference (when == .. @@ -80,6 +79,7 @@ public string FileId /// /// Describes the kind of annotation /// Identifies the referenced resource. + [JsonConstructor] public StreamingAnnotationContent( AnnotationKind kind, string referenceId) From ec272fc91e24b378272bcc4c6ee41167fda78e91 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Tue, 13 May 2025 16:34:07 -0700 Subject: [PATCH 10/20] Sync suppression --- .../CompatibilitySuppressions.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dotnet/src/SemanticKernel.Abstractions/CompatibilitySuppressions.xml b/dotnet/src/SemanticKernel.Abstractions/CompatibilitySuppressions.xml index 195237c69926..f925c94bf1c3 100644 --- a/dotnet/src/SemanticKernel.Abstractions/CompatibilitySuppressions.xml +++ b/dotnet/src/SemanticKernel.Abstractions/CompatibilitySuppressions.xml @@ -71,6 +71,13 @@ lib/net8.0/Microsoft.SemanticKernel.Abstractions.dll true + + CP0002 + M:Microsoft.SemanticKernel.Agents.StreamingAnnotationContent.set_FileId(System.String) + lib/net8.0/Microsoft.SemanticKernel.Abstractions.dll + lib/net8.0/Microsoft.SemanticKernel.Abstractions.dll + true + CP0002 M:Microsoft.SemanticKernel.Agents.StreamingAnnotationContent.set_Quote(System.String) @@ -190,6 +197,13 @@ lib/netstandard2.0/Microsoft.SemanticKernel.Abstractions.dll true + + CP0002 + M:Microsoft.SemanticKernel.Agents.StreamingAnnotationContent.set_FileId(System.String) + lib/netstandard2.0/Microsoft.SemanticKernel.Abstractions.dll + lib/netstandard2.0/Microsoft.SemanticKernel.Abstractions.dll + true + CP0002 M:Microsoft.SemanticKernel.Agents.StreamingAnnotationContent.set_Quote(System.String) From 9651a4b407aea3d1ebd0d501e6cbb78f3e343932 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 15 May 2025 17:41:36 -0700 Subject: [PATCH 11/20] Stage partial result --- dotnet/Directory.Packages.props | 4 +- dotnet/nuget.config | 7 +- .../Agents/AzureAIAgent_FileManipulation.cs | 8 +- .../AzureAIAgent/Step01_AzureAIAgent.cs | 2 +- .../Step02_AzureAIAgent_Plugins.cs | 6 +- .../AzureAIAgent/Step03_AzureAIAgent_Chat.cs | 4 +- .../Step04_AzureAIAgent_CodeInterpreter.cs | 4 +- .../Step05_AzureAIAgent_FileSearch.cs | 14 +-- .../Step06_AzureAIAgent_OpenAPI.cs | 4 +- .../Step07_AzureAIAgent_Functions.cs | 4 +- .../Step08_AzureAIAgent_Declarative.cs | 8 +- .../Step09_AzureAIAgent_BingGrounding.cs | 9 +- .../AzureAI/AzureAIAgent.ClientFactory.cs | 40 +++--- .../Agents/AzureAI/AzureAIClientProvider.cs | 119 ------------------ .../Extensions/AgentDefinitionExtensions.cs | 30 +---- .../AzureAI/Extensions/AgentRunExtensions.cs | 22 ++-- .../AzureAI/Internal/AgentThreadActions.cs | 72 +++++------ .../AzureAI/AzureAIClientProviderTests.cs | 72 ----------- .../samples/AgentUtilities/BaseAzureTest.cs | 9 +- 19 files changed, 104 insertions(+), 334 deletions(-) delete mode 100644 dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs delete mode 100644 dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props index e669183b3127..9a513840e413 100644 --- a/dotnet/Directory.Packages.props +++ b/dotnet/Directory.Packages.props @@ -17,9 +17,9 @@ - + - + diff --git a/dotnet/nuget.config b/dotnet/nuget.config index a90724f5fca8..7d7626e18f30 100644 --- a/dotnet/nuget.config +++ b/dotnet/nuget.config @@ -3,15 +3,10 @@ - - - + - - - diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs index 6d7ebcbb557a..6292339d35e7 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs @@ -16,10 +16,10 @@ public class AzureAIAgent_FileManipulation(ITestOutputHelper output) : BaseAzure public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() { await using Stream stream = EmbeddedResource.ReadStream("sales.csv")!; - PersistentAgentFile fileInfo = await this.Client.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "sales.csv"); + PersistentAgentFileInfo fileInfo = await this.Client.Files.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "sales.csv"); // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new CodeInterpreterToolDefinition()], toolResources: @@ -43,8 +43,8 @@ public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); - await this.Client.DeleteFileAsync(fileInfo.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); + await this.Client.Files.DeleteFileAsync(fileInfo.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs index 6b8ccc83c9c6..3765ffa86074 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs @@ -20,7 +20,7 @@ public async Task UseTemplateForAzureAgent() string generateStoryYaml = EmbeddedResource.Read("GenerateStory.yaml"); PromptTemplateConfig templateConfig = KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml); // Instructions, Name and Description properties defined via the PromptTemplateConfig. - PersistentAgent definition = await this.Client.CreateAgentAsync(TestConfiguration.AzureAI.ChatModelId, templateConfig.Name, templateConfig.Description, templateConfig.Template); + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync(TestConfiguration.AzureAI.ChatModelId, templateConfig.Name, templateConfig.Description, templateConfig.Template); AzureAIAgent agent = new( definition, this.Client, diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs index 629f0ae5f15f..666d2a5b650b 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs @@ -37,7 +37,7 @@ public async Task UseAzureAgentWithPlugin() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } } @@ -58,14 +58,14 @@ public async Task UseAzureAgentWithPluginEnumParameter() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } } private async Task CreateAzureAgentAsync(KernelPlugin plugin, string? instructions = null, string? name = null) { // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, name, null, diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs index e59e5b14378e..0f9a7a9823f2 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs @@ -39,13 +39,13 @@ Consider suggestions when refining an idea. public async Task UseGroupChatWithTwoAgents() { // Define the agents - PersistentAgent reviewerModel = await this.Client.CreateAgentAsync( + PersistentAgent reviewerModel = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, ReviewerName, null, ReviewerInstructions); AzureAIAgent agentReviewer = new(reviewerModel, this.Client); - PersistentAgent writerModel = await this.Client.CreateAgentAsync( + PersistentAgent writerModel = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, CopyWriterName, null, diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs index c396a0e9b984..ca7558cd6a81 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step04_AzureAIAgent_CodeInterpreter.cs @@ -16,7 +16,7 @@ public class Step04_AzureAIAgent_CodeInterpreter(ITestOutputHelper output) : Bas public async Task UseCodeInterpreterToolWithAgent() { // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new CodeInterpreterToolDefinition()]); AzureAIAgent agent = new(definition, this.Client); @@ -32,7 +32,7 @@ public async Task UseCodeInterpreterToolWithAgent() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs index a1a31d7b8f41..9fc515f159af 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step05_AzureAIAgent_FileSearch.cs @@ -18,12 +18,12 @@ public async Task UseFileSearchToolWithAgent() // Define the agent await using Stream stream = EmbeddedResource.ReadStream("employees.pdf")!; - PersistentAgentFile fileInfo = await this.Client.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "employees.pdf"); - VectorStore fileStore = - await this.Client.CreateVectorStoreAsync( + PersistentAgentFileInfo fileInfo = await this.Client.Files.UploadFileAsync(stream, PersistentAgentFilePurpose.Agents, "employees.pdf"); + PersistentAgentsVectorStore fileStore = + await this.Client.VectorStores.CreateVectorStoreAsync( [fileInfo.Id], metadata: new Dictionary() { { SampleMetadataKey, bool.TrueString } }); - PersistentAgent agentModel = await this.Client.CreateAgentAsync( + PersistentAgent agentModel = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new FileSearchToolDefinition()], toolResources: new() @@ -49,9 +49,9 @@ await this.Client.CreateVectorStoreAsync( finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); - await this.Client.DeleteVectorStoreAsync(fileStore.Id); - await this.Client.DeleteFileAsync(fileInfo.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); + await this.Client.VectorStores.DeleteVectorStoreAsync(fileStore.Id); + await this.Client.Files.DeleteFileAsync(fileInfo.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs index 712b2f40e40f..0514069f3937 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step06_AzureAIAgent_OpenAPI.cs @@ -24,7 +24,7 @@ public async Task UseOpenAPIToolWithAgent() string apiWeather = EmbeddedResource.Read("weather.json"); // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [ @@ -45,7 +45,7 @@ public async Task UseOpenAPIToolWithAgent() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs index 2ff178767dab..c88da8509695 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step07_AzureAIAgent_Functions.cs @@ -28,7 +28,7 @@ public async Task UseSingleAgentWithFunctionTools() KernelPlugin plugin = KernelPluginFactory.CreateFromType(); var tools = plugin.Select(f => f.ToToolDefinition(plugin.Name)); - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( model: TestConfiguration.AzureAI.ChatModelId, name: HostName, description: null, @@ -53,7 +53,7 @@ public async Task UseSingleAgentWithFunctionTools() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index d47d1c7e901a..9436c20e68b9 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -383,7 +383,9 @@ public async Task AzureAIAgentWithTemplate() AzureAIAgentFactory factory = new(); var promptTemplateFactory = new KernelPromptTemplateFactory(); - var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot); + var agent = + await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot) ?? + throw new InvalidOperationException("Unable to create agent"); var options = new AgentInvokeOptions() { @@ -405,8 +407,8 @@ public async Task AzureAIAgentWithTemplate() } finally { - var azureaiAgent = agent as AzureAIAgent; - await azureaiAgent!.Client.DeleteAgentAsync(azureaiAgent.Id); + var azureaiAgent = (AzureAIAgent)agent; + await azureaiAgent.Client.Administration.DeleteAgentAsync(azureaiAgent.Id); if (agentThread is not null) { diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs index 44a21f3094ce..736fd2d70a2e 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs @@ -4,7 +4,6 @@ using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; -using AAIP = Azure.AI.Projects.OneDP; namespace GettingStarted.AzureAgents; @@ -26,7 +25,7 @@ public async Task UseBingGroundingToolWithAgent() { ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } }; - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new BingGroundingToolDefinition(toolConnections)]); AzureAIAgent agent = new(definition, this.Client); @@ -43,7 +42,7 @@ public async Task UseBingGroundingToolWithAgent() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. @@ -72,7 +71,7 @@ public async Task UseBingGroundingToolWithStreaming() { ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } }; - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, tools: [new BingGroundingToolDefinition(toolConnections)]); AzureAIAgent agent = new(definition, this.Client); @@ -98,7 +97,7 @@ public async Task UseBingGroundingToolWithStreaming() finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs index 72fed94725c8..d0e9afb773b3 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs @@ -14,24 +14,24 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// public sealed partial class AzureAIAgent : Agent { - /// - /// Produces a . - /// - /// The Azure AI Foundry project endpoint. - /// A credential used to authenticate to an Azure Service. - /// A custom for HTTP requests. - public static PersistentAgentsClient CreateAgentsClient( - Uri endpoint, - AzureKeyCredential credential, - HttpClient? httpClient = null) - { - Verify.NotNull(endpoint, nameof(endpoint)); - Verify.NotNull(credential, nameof(credential)); + ///// // %%% REMOVE ME + ///// Produces a . + ///// + ///// The Azure AI Foundry project endpoint. + ///// A credential used to authenticate to an Azure Service. + ///// A custom for HTTP requests. + //public static PersistentAgentsClient CreateAgentsClient( + // string endpoint, + // AzureKeyCredential credential, + // HttpClient? httpClient = null) + //{ + // Verify.NotNull(endpoint, nameof(endpoint)); + // Verify.NotNull(credential, nameof(credential)); - PersistentAgentsClientOptions clientOptions = CreateAzureClientOptions(httpClient); + // PersistentAgentsAdministrationClientOptions clientOptions = CreateAzureClientOptions(httpClient); - return new PersistentAgentsClient(endpoint, credential, clientOptions); - } + // return new PersistentAgentsClient(endpoint, credential, clientOptions); + //} /// /// Produces a . @@ -41,21 +41,21 @@ public static PersistentAgentsClient CreateAgentsClient( /// A custom for HTTP requests. public static PersistentAgentsClient CreateAgentsClient ( - Uri endpoint, + string endpoint, TokenCredential credential, HttpClient? httpClient = null) { Verify.NotNull(endpoint, nameof(endpoint)); Verify.NotNull(credential, nameof(credential)); - PersistentAgentsClientOptions clientOptions = CreateAzureClientOptions(httpClient); + PersistentAgentsAdministrationClientOptions clientOptions = CreateAzureClientOptions(httpClient); return new PersistentAgentsClient(endpoint, credential, clientOptions); } - private static PersistentAgentsClientOptions CreateAzureClientOptions(HttpClient? httpClient) + private static PersistentAgentsAdministrationClientOptions CreateAzureClientOptions(HttpClient? httpClient) { - PersistentAgentsClientOptions options = new(); + PersistentAgentsAdministrationClientOptions options = new(); options.AddPolicy(new SemanticKernelHeadersPolicy(), HttpPipelinePosition.PerCall); diff --git a/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs b/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs deleted file mode 100644 index f1536a964203..000000000000 --- a/dotnet/src/Agents/AzureAI/AzureAIClientProvider.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using Azure.AI.Projects; -using Azure.AI.Projects.OneDP; -using Azure.Core; -using Azure.Core.Pipeline; -using Microsoft.SemanticKernel.Http; - -namespace Microsoft.SemanticKernel.Agents.AzureAI; - -/// -/// Provides an for use by . -/// -[Obsolete("Use AzureAIAgent.CreateAzureAIClient(...)")] -public sealed class AzureAIClientProvider -{ - private AgentsClient? _agentsClient; - - /// - /// Gets an active client instance. - /// - public AIProjectClient Client { get; } - - /// - /// Gets an active assistant client instance. - /// - public AgentsClient AgentsClient => this._agentsClient ??= this.Client.GetAgentsClient(); - - /// - /// Configuration keys required for management. - /// - internal IReadOnlyList ConfigurationKeys { get; } - - private AzureAIClientProvider(AIProjectClient client, IEnumerable keys) - { - this.Client = client; - this.ConfigurationKeys = [.. keys]; - } - - /// - /// Produces a . - /// - /// The Azure AI Foundry project connection string, in the form `endpoint;subscription_id;resource_group_name;project_name`. - /// A credential used to authenticate to an Azure Service. - /// A custom for HTTP requests. - public static AzureAIClientProvider FromEndpoint( - Uri endpoint, - TokenCredential credential, - HttpClient? httpClient = null) - { - Verify.NotNull(endpoint, nameof(endpoint)); - Verify.NotNull(credential, nameof(credential)); - - AIProjectClientOptions clientOptions = CreateAzureClientOptions(httpClient); - - return new(new AIProjectClient(endpoint, credential, clientOptions), CreateConfigurationKeys(endpoint, httpClient)); - } - - /// - /// Provides a client instance directly. - /// - public static AzureAIClientProvider FromClient(AIProjectClient client) - { - return new(client, [client.GetType().FullName!, client.GetHashCode().ToString()]); - } - - internal static AIProjectClientOptions CreateAzureClientOptions(HttpClient? httpClient) - { - AIProjectClientOptions options = - new() - { - Diagnostics = { - ApplicationId = HttpHeaderConstant.Values.UserAgent, - } - }; - - options.AddPolicy(new SemanticKernelHeadersPolicy(), HttpPipelinePosition.PerCall); - - if (httpClient is not null) - { - options.Transport = new HttpClientTransport(httpClient); - // Disable retry policy if and only if a custom HttpClient is provided. - options.RetryPolicy = new RetryPolicy(maxRetries: 0); - } - - return options; - } - - private static IEnumerable CreateConfigurationKeys(Uri endpoint, HttpClient? httpClient) - { - yield return endpoint.ToString(); - - if (httpClient is not null) - { - if (httpClient.BaseAddress is not null) - { - yield return httpClient.BaseAddress.AbsoluteUri; - } - - foreach (string header in httpClient.DefaultRequestHeaders.SelectMany(h => h.Value)) - { - yield return header; - } - } - } - - private class SemanticKernelHeadersPolicy : HttpPipelineSynchronousPolicy - { - public override void OnSendingRequest(HttpMessage message) - { - message.Request.Headers.Add( - HttpHeaderConstant.Names.SemanticKernelVersion, - HttpHeaderConstant.Values.GetAssemblyVersion(typeof(AzureAIAgent))); - } - } -} diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs index 940fc6b11c18..2b80225a6c90 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs @@ -20,9 +20,7 @@ internal static class AgentDefinitionExtensions private const string CodeInterpreterType = "code_interpreter"; private const string FileSearchType = "file_search"; private const string FunctionType = "function"; - private const string MicrosoftFabricType = "fabric_aiskill"; private const string OpenApiType = "openapi"; - private const string SharepointGroundingType = "sharepoint_grounding"; private static readonly string[] s_validToolTypes = [ @@ -32,9 +30,7 @@ internal static class AgentDefinitionExtensions CodeInterpreterType, FileSearchType, FunctionType, - MicrosoftFabricType, OpenApiType, - SharepointGroundingType ]; private const string Endpoint = "endpoint"; @@ -58,9 +54,7 @@ public static IEnumerable GetAzureToolDefinitions(this AgentDefi CodeInterpreterType => CreateCodeInterpreterToolDefinition(tool), FileSearchType => CreateFileSearchToolDefinition(tool), FunctionType => CreateFunctionToolDefinition(tool), - MicrosoftFabricType => CreateMicrosoftFabricToolDefinition(tool), OpenApiType => CreateOpenApiToolDefinition(tool), - SharepointGroundingType => CreateSharepointGroundingToolDefinition(tool), _ => throw new NotSupportedException($"Unable to create Azure AI tool definition because of unsupported tool type: {tool.Type}, supported tool types are: {string.Join(",", s_validToolTypes)}"), }; }) ?? []; @@ -127,7 +121,7 @@ public static PersistentAgentsClient GetAgentsClient(this AgentDefinition agentD #pragma warning restore CA2000 // Dispose objects before losing scope var tokenCredential = kernel.Services.GetRequiredService(); - return AzureAIAgent.CreateAgentsClient(new Uri(endpoint), tokenCredential, httpClient); + return AzureAIAgent.CreateAgentsClient(endpoint, tokenCredential, httpClient); } } @@ -183,7 +177,7 @@ public static PersistentAgentsClient GetAgentsClient(this AgentDefinition agentD return null; } - private static AzureAISearchResource? GetAzureAISearchResource(this AgentDefinition agentDefinition) + private static AzureAISearchToolResource? GetAzureAISearchResource(this AgentDefinition agentDefinition) { Verify.NotNull(agentDefinition); @@ -204,7 +198,7 @@ public static PersistentAgentsClient GetAgentsClient(this AgentDefinition agentD string filter = azureAISearch.GetFilter() ?? string.Empty; AzureAISearchQueryType? queryType = azureAISearch.GetAzureAISearchQueryType(); - return new AzureAISearchResource(indexConnectionId, indexName, topK, filter, queryType); + return new AzureAISearchToolResource(indexConnectionId, indexName, topK, filter, queryType); } return null; @@ -269,15 +263,6 @@ private static FunctionToolDefinition CreateFunctionToolDefinition(AgentToolDefi return new FunctionToolDefinition(name, description, parameters); } - private static MicrosoftFabricToolDefinition CreateMicrosoftFabricToolDefinition(AgentToolDefinition tool) - { - Verify.NotNull(tool); - - ToolConnectionList fabricAiSkill = tool.GetToolConnectionList(); - - return new MicrosoftFabricToolDefinition(fabricAiSkill); - } - private static OpenApiToolDefinition CreateOpenApiToolDefinition(AgentToolDefinition tool) { Verify.NotNull(tool); @@ -291,14 +276,5 @@ private static OpenApiToolDefinition CreateOpenApiToolDefinition(AgentToolDefini return new OpenApiToolDefinition(name, description, spec, auth); } - - private static SharepointToolDefinition CreateSharepointGroundingToolDefinition(AgentToolDefinition tool) - { - Verify.NotNull(tool); - - ToolConnectionList sharepointGrounding = tool.GetToolConnectionList(); - - return new SharepointToolDefinition(sharepointGrounding); - } #endregion } diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs index daba5e119f34..57bbc8d92df1 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Azure; using Azure.AI.Agents.Persistent; using Microsoft.SemanticKernel.Agents.AzureAI.Internal; @@ -22,16 +23,11 @@ public static async IAsyncEnumerable GetStepsAsync( ThreadRun run, [EnumeratorCancellation] CancellationToken cancellationToken) { - PageableList? steps = null; - do + AsyncPageable? steps = client.Runs.GetRunStepsAsync(run, cancellationToken: cancellationToken); + await foreach (RunStep step in steps.ConfigureAwait(false)) { - steps = await client.GetRunStepsAsync(run, after: steps?.LastId, cancellationToken: cancellationToken).ConfigureAwait(false); - foreach (RunStep step in steps) - { - yield return step; - } + yield return step; } - while (steps?.HasMore ?? false); } public static async Task CreateAsync( @@ -43,10 +39,10 @@ public static async Task CreateAsync( AzureAIInvocationOptions? invocationOptions, CancellationToken cancellationToken) { - TruncationObject? truncationStrategy = GetTruncationStrategy(invocationOptions); + Truncation? truncationStrategy = GetTruncationStrategy(invocationOptions); BinaryData? responseFormat = GetResponseFormat(invocationOptions); return - await client.CreateRunAsync( + await client.Runs.CreateRunAsync( threadId, agent.Id, overrideModelName: invocationOptions?.ModelName, @@ -75,7 +71,7 @@ await client.CreateRunAsync( null; } - private static TruncationObject? GetTruncationStrategy(AzureAIInvocationOptions? invocationOptions) + private static Truncation? GetTruncationStrategy(AzureAIInvocationOptions? invocationOptions) { return invocationOptions?.TruncationMessageCount == null ? null : @@ -94,10 +90,10 @@ public static IAsyncEnumerable CreateStreamingAsync( AzureAIInvocationOptions? invocationOptions, CancellationToken cancellationToken) { - TruncationObject? truncationStrategy = GetTruncationStrategy(invocationOptions); + Truncation? truncationStrategy = GetTruncationStrategy(invocationOptions); BinaryData? responseFormat = GetResponseFormat(invocationOptions); return - client.CreateRunStreamingAsync( + client.Runs.CreateRunStreamingAsync( threadId, agent.Id, overrideModelName: invocationOptions?.ModelName, diff --git a/dotnet/src/Agents/AzureAI/Internal/AgentThreadActions.cs b/dotnet/src/Agents/AzureAI/Internal/AgentThreadActions.cs index 8a95eccc8750..df41bf1aceee 100644 --- a/dotnet/src/Agents/AzureAI/Internal/AgentThreadActions.cs +++ b/dotnet/src/Agents/AzureAI/Internal/AgentThreadActions.cs @@ -45,7 +45,7 @@ internal static class AgentThreadActions /// The thread identifier public static async Task CreateThreadAsync(PersistentAgentsClient client, CancellationToken cancellationToken = default) { - PersistentAgentThread thread = await client.CreateThreadAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + PersistentAgentThread thread = await client.Threads.CreateThreadAsync(cancellationToken: cancellationToken).ConfigureAwait(false); return thread.Id; } @@ -71,7 +71,7 @@ public static async Task CreateMessageAsync(PersistentAgentsClient client, strin return; } - await client.CreateMessageAsync( + await client.Messages.CreateMessageAsync( threadId, role: message.Role == AuthorRole.User ? MessageRole.User : MessageRole.Agent, content, @@ -93,34 +93,30 @@ public static async IAsyncEnumerable GetMessagesAsync(Persis Dictionary agentNames = []; // Cache agent names by their identifier string? lastId = null; - PageableList? messages = null; - do + AsyncPageable? messages = client.Messages.GetMessagesAsync(threadId, runId: null, limit: null, messageOrder ?? ListSortOrder.Descending, after: lastId, before: null, cancellationToken); + await foreach (PersistentThreadMessage message in messages.ConfigureAwait(false)) { - messages = await client.GetMessagesAsync(threadId, runId: null, limit: null, messageOrder ?? ListSortOrder.Descending, after: lastId, before: null, cancellationToken).ConfigureAwait(false); - foreach (ThreadMessage message in messages) + lastId = message.Id; + string? assistantName = null; + if (!string.IsNullOrWhiteSpace(message.AssistantId) && + !agentNames.TryGetValue(message.AssistantId, out assistantName)) { - lastId = message.Id; - string? assistantName = null; - if (!string.IsNullOrWhiteSpace(message.AssistantId) && - !agentNames.TryGetValue(message.AssistantId, out assistantName)) + PersistentAgent assistant = await client.Administration.GetAgentAsync(message.AssistantId, cancellationToken).ConfigureAwait(false); + if (!string.IsNullOrWhiteSpace(assistant.Name)) { - PersistentAgent assistant = await client.GetAgentAsync(message.AssistantId, cancellationToken).ConfigureAwait(false); - if (!string.IsNullOrWhiteSpace(assistant.Name)) - { - agentNames.Add(assistant.Id, assistant.Name); - } + agentNames.Add(assistant.Id, assistant.Name); } + } - assistantName ??= message.AssistantId; + assistantName ??= message.AssistantId; - ChatMessageContent content = GenerateMessageContent(assistantName, message); + ChatMessageContent content = GenerateMessageContent(assistantName, message); - if (content.Items.Count > 0) - { - yield return content; - } + if (content.Items.Count > 0) + { + yield return content; } - } while (messages?.HasMore ?? false); + } } /// @@ -219,7 +215,7 @@ await functionProcessor.InvokeFunctionCallsAsync( // Process tool output ToolOutput[] toolOutputs = GenerateToolOutputs(functionResults); - await client.SubmitToolOutputsToRunAsync(run, toolOutputs, cancellationToken).ConfigureAwait(false); + await client.Runs.SubmitToolOutputsToRunAsync(run, toolOutputs, cancellationToken).ConfigureAwait(false); } logger.LogAzureAIAgentProcessedRunSteps(nameof(InvokeAsync), functionCalls.Length, run.Id, threadId); @@ -269,7 +265,7 @@ await functionProcessor.InvokeFunctionCallsAsync( { // Retrieve the message RunStepMessageCreationDetails messageDetails = (RunStepMessageCreationDetails)completedStep.StepDetails; - ThreadMessage? message = await RetrieveMessageAsync(client, threadId, messageDetails.MessageCreation.MessageId, agent.PollingOptions.MessageSynchronizationDelay, cancellationToken).ConfigureAwait(false); + PersistentThreadMessage? message = await RetrieveMessageAsync(client, threadId, messageDetails.MessageCreation.MessageId, agent.PollingOptions.MessageSynchronizationDelay, cancellationToken).ConfigureAwait(false); if (message is not null) { @@ -314,7 +310,7 @@ async Task PollRunStatusAsync() try { - run = await client.GetRunAsync(threadId, run.Id, cancellationToken).ConfigureAwait(false); + run = await client.Runs.GetRunAsync(threadId, run.Id, cancellationToken).ConfigureAwait(false); } // The presence of a `Status` code means the server responded with error...always fail in that case catch (ClientResultException clientException) when (clientException.Status <= 0) @@ -496,7 +492,7 @@ await functionProcessor.InvokeFunctionCallsAsync( // Process tool output ToolOutput[] toolOutputs = GenerateToolOutputs(functionResults); - asyncUpdates = client.SubmitToolOutputsToStreamAsync(run, toolOutputs, cancellationToken); + asyncUpdates = client.Runs.SubmitToolOutputsToStreamAsync(run, toolOutputs, cancellationToken); foreach (RunStep step in activeSteps) { @@ -513,7 +509,7 @@ await functionProcessor.InvokeFunctionCallsAsync( { if (step.StepDetails is RunStepMessageCreationDetails messageDetails) { - ThreadMessage? message = + PersistentThreadMessage? message = await RetrieveMessageAsync( client, threadId, @@ -554,17 +550,17 @@ await RetrieveMessageAsync( logger.LogAzureAIAgentCompletedRun(nameof(InvokeAsync), run?.Id ?? "Failed", threadId); } - private static ChatMessageContent GenerateMessageContent(string? assistantName, ThreadMessage message, RunStep? completedStep = null, ILogger? logger = null) + private static ChatMessageContent GenerateMessageContent(string? assistantName, PersistentThreadMessage message, RunStep? completedStep = null, ILogger? logger = null) { AuthorRole role = new(message.Role.ToString()); Dictionary? metadata = new() { - { nameof(ThreadMessage.CreatedAt), message.CreatedAt }, - { nameof(ThreadMessage.AssistantId), message.AssistantId }, - { nameof(ThreadMessage.ThreadId), message.ThreadId }, - { nameof(ThreadMessage.RunId), message.RunId }, + { nameof(PersistentThreadMessage.CreatedAt), message.CreatedAt }, + { nameof(PersistentThreadMessage.AssistantId), message.AssistantId }, + { nameof(PersistentThreadMessage.ThreadId), message.ThreadId }, + { nameof(PersistentThreadMessage.RunId), message.RunId }, { nameof(MessageContentUpdate.MessageId), message.Id }, }; @@ -695,16 +691,16 @@ private static StreamingChatMessageContent GenerateStreamingMessageContent(strin EndIndex = fileCitationAnnotation.EndIndex, }; } - if (annotation is MessageTextUrlCitationAnnotation urlCitationAnnotation) + if (annotation is MessageTextUriCitationAnnotation urlCitationAnnotation) { return new AnnotationContent( kind: AnnotationKind.UrlCitation, label: annotation.Text, - referenceId: urlCitationAnnotation.UrlCitation.Url) + referenceId: urlCitationAnnotation.UriCitation.Uri) { InnerContent = annotation, - Title = urlCitationAnnotation.UrlCitation.Title, + Title = urlCitationAnnotation.UriCitation.Title, StartIndex = urlCitationAnnotation.StartIndex, EndIndex = urlCitationAnnotation.EndIndex, }; @@ -882,9 +878,9 @@ private static ToolOutput[] GenerateToolOutputs(FunctionResultContent[] function return toolOutputs; } - private static async Task RetrieveMessageAsync(PersistentAgentsClient client, string threadId, string messageId, TimeSpan syncDelay, CancellationToken cancellationToken) + private static async Task RetrieveMessageAsync(PersistentAgentsClient client, string threadId, string messageId, TimeSpan syncDelay, CancellationToken cancellationToken) { - ThreadMessage? message = null; + PersistentThreadMessage? message = null; bool retry = false; int count = 0; @@ -892,7 +888,7 @@ private static ToolOutput[] GenerateToolOutputs(FunctionResultContent[] function { try { - message = await client.GetMessageAsync(threadId, messageId, cancellationToken).ConfigureAwait(false); + message = await client.Messages.GetMessageAsync(threadId, messageId, cancellationToken).ConfigureAwait(false); } catch (RequestFailedException exception) { diff --git a/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs deleted file mode 100644 index 17e93948dd05..000000000000 --- a/dotnet/src/Agents/UnitTests/AzureAI/AzureAIClientProviderTests.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -using System; -using System.Net.Http; -using Azure.AI.Projects.OneDP; -using Azure.Identity; -using Microsoft.SemanticKernel.Agents.AzureAI; -using Moq; -using Xunit; - -namespace SemanticKernel.Agents.UnitTests.AzureAI; - -/// -/// Unit testing of . -/// -public class AzureAIClientProviderTests -{ - /// - /// Verify that provisioning of client for Azure OpenAI. - /// - [Fact] - public void VerifyAzureAIClientProviderDefault() - { - // Act - AzureAIClientProvider provider = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential()); - - // Assert - Assert.NotNull(provider.Client); - } - - /// - /// Verify that the factory can create a client with http proxy. - /// - [Fact] - public void VerifyAzureAIClientProviderWithHttpClient() - { - // Arrange - using HttpClient httpClient = new() { BaseAddress = new Uri("http://myproxy:9819") }; - - // Act - AzureAIClientProvider provider = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential(), httpClient); - - // Assert - Assert.NotNull(provider.Client); - - // Arrange - using HttpClient httpClientWithHeaders = new() { BaseAddress = new Uri("http://myproxy:9819") }; - httpClientWithHeaders.DefaultRequestHeaders.Add("X-Test", "Test"); - - // Act - AzureAIClientProvider providerWithHeaders = AzureAIClientProvider.FromEndpoint(new Uri("https://test"), new AzureCliCredential(), httpClientWithHeaders); - - // Assert - Assert.NotNull(providerWithHeaders.Client); - - Assert.NotEqual(provider.ConfigurationKeys.Count, providerWithHeaders.ConfigurationKeys.Count); - } - - /// - /// Verify that the factory can accept an client that already exists. - /// - [Fact] - public void VerifyAzureAIClientProviderFromClient() - { - // Arrange - Mock mockClient = new(); - AzureAIClientProvider provider = AzureAIClientProvider.FromClient(mockClient.Object); - - // Assert - Assert.NotNull(provider.Client); - Assert.Equal(mockClient.Object, provider.Client); - } -} diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs index 36f084831393..f76cee85de92 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs @@ -16,10 +16,7 @@ public abstract class BaseAzureAgentTest : BaseAgentsTest Date: Thu, 15 May 2025 19:02:59 -0700 Subject: [PATCH 12/20] Updated --- dotnet/Directory.Packages.props | 1 - .../Concepts/Agents/AzureAIAgent_Streaming.cs | 6 +- .../Samples/AzureAIAgentWithMCPToolsSample.cs | 6 +- .../AzureAIAgent/Step01_AzureAIAgent.cs | 2 +- .../Step08_AzureAIAgent_Declarative.cs | 2 +- .../Step09_AzureAIAgent_BingGrounding.cs | 24 ++---- .../Step10_MultiAgent_Declarative.cs | 4 +- .../src/Agents/AzureAI/Agents.AzureAI.csproj | 1 - .../AzureAI/AzureAIAgent.ClientFactory.cs | 24 +----- dotnet/src/Agents/AzureAI/AzureAIAgent.cs | 2 +- .../src/Agents/AzureAI/AzureAIAgentThread.cs | 4 +- dotnet/src/Agents/AzureAI/AzureAIChannel.cs | 2 +- .../AzureAI/Definition/AzureAIAgentFactory.cs | 4 +- .../Extensions/AgentDefinitionExtensions.cs | 4 +- .../AzureAI/Extensions/AgentRunExtensions.cs | 3 +- .../AgentToolDefinitionExtensions.cs | 20 +---- .../AzureAI/Internal/AgentMessageFactory.cs | 4 +- .../Definition/AzureAIAgentFactoryTests.cs | 4 +- .../Agents/UnitTests/Yaml/AgentYamlTests.cs | 4 +- .../Yaml/AzureAIKernelAgentYamlTests.cs | 76 +------------------ .../Agents/AzureAIAgentTests.cs | 13 ++-- .../AzureAIAgentFixture.cs | 18 ++--- .../samples/AgentUtilities/BaseAzureTest.cs | 6 -- 23 files changed, 53 insertions(+), 181 deletions(-) diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props index 9a513840e413..d3997cd7f527 100644 --- a/dotnet/Directory.Packages.props +++ b/dotnet/Directory.Packages.props @@ -21,7 +21,6 @@ - diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs index ec834b3b2e19..62b1ee5ed86c 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs @@ -20,7 +20,7 @@ public async Task UseStreamingAgentAsync() const string AgentInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound."; // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, @@ -46,7 +46,7 @@ public async Task UseStreamingAssistantAgentWithPluginAsync() const string AgentInstructions = "Answer questions about the menu."; // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, @@ -75,7 +75,7 @@ public async Task UseStreamingAssistantWithCodeInterpreterAsync() const string AgentInstructions = "Solve math problems with code."; // Define the agent - PersistentAgent definition = await this.Client.CreateAgentAsync( + PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, AgentName, null, diff --git a/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs b/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs index 9edc49ef9bfb..7fd1e1c7fb14 100644 --- a/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs +++ b/dotnet/samples/Demos/ModelContextProtocolClientServer/MCPClient/Samples/AzureAIAgentWithMCPToolsSample.cs @@ -68,7 +68,7 @@ public static async Task RunAsync() await response!.Thread.DeleteAsync(); // Delete the agent after use - await agent.Client.DeleteAgentAsync(agent.Id); + await agent.Client.Administration.DeleteAgentAsync(agent.Id); } /// @@ -96,9 +96,9 @@ private static async Task CreateAzureAIAgentAsync(Kernel kernel, s string modelId = config["AzureAI:ChatModelId"] ?? "gpt-4o-mini"; // Create the Azure AI Agent - PersistentAgentsClient agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(endpoint), new AzureCliCredential()); + PersistentAgentsClient agentsClient = AzureAIAgent.CreateAgentsClient(endpoint, new AzureCliCredential()); - PersistentAgent agent = await agentsClient.CreateAgentAsync(modelId, name, null, instructions); + PersistentAgent agent = await agentsClient.Administration.CreateAgentAsync(modelId, name, null, instructions); return new AzureAIAgent(agent, agentsClient) { diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs index 3765ffa86074..e348f065eb13 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs @@ -53,7 +53,7 @@ await InvokeAgentAsync( finally { await thread.DeleteAsync(); - await this.Client.DeleteAgentAsync(agent.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); } // Local function to invoke agent and display the response. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index 9436c20e68b9..62cc2685f435 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -451,7 +451,7 @@ private async Task InvokeAgentAsync(Agent agent, string input, bool? deleteAgent { var azureaiAgent = agent as AzureAIAgent; Assert.NotNull(azureaiAgent); - await azureaiAgent.Client.DeleteAgentAsync(azureaiAgent.Id); + await azureaiAgent.Client.Administration.DeleteAgentAsync(azureaiAgent.Id); if (agentThread is not null) { diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs index 736fd2d70a2e..acd085d2791d 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step09_AzureAIAgent_BingGrounding.cs @@ -16,18 +16,11 @@ public class Step09_AzureAIAgent_BingGrounding(ITestOutputHelper output) : BaseA public async Task UseBingGroundingToolWithAgent() { // Access the BingGrounding connection - AAIP.AIProjectClient projectClient = this.CreateProjectClient(); - AAIP.Connections connectionsClient = projectClient.GetConnectionsClient(); - AAIP.Connection bingConnectionResponse = await connectionsClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); - - // Define the agent - ToolConnectionList toolConnections = new() - { - ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } - }; + BingGroundingSearchConfiguration bingToolConfiguration = new(TestConfiguration.AzureAI.BingConnectionId); + BingGroundingSearchToolParameters bingToolParameters = new([bingToolConfiguration]); PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, - tools: [new BingGroundingToolDefinition(toolConnections)]); + tools: [new BingGroundingToolDefinition(bingToolParameters)]); AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. @@ -62,18 +55,13 @@ async Task InvokeAgentAsync(string input) public async Task UseBingGroundingToolWithStreaming() { // Access the BingGrounding connection - AAIP.AIProjectClient projectClient = this.CreateProjectClient(); - AAIP.Connections connectionsClient = projectClient.GetConnectionsClient(); - AAIP.Connection bingConnectionResponse = await connectionsClient.GetConnectionAsync(TestConfiguration.AzureAI.BingConnectionId); + BingGroundingSearchConfiguration bingToolConfiguration = new(TestConfiguration.AzureAI.BingConnectionId); + BingGroundingSearchToolParameters bingToolParameters = new([bingToolConfiguration]); // Define the agent - ToolConnectionList toolConnections = new() - { - ConnectionList = { new ToolConnection(bingConnectionResponse.Name) } - }; PersistentAgent definition = await this.Client.Administration.CreateAgentAsync( TestConfiguration.AzureAI.ChatModelId, - tools: [new BingGroundingToolDefinition(toolConnections)]); + tools: [new BingGroundingToolDefinition(bingToolParameters)]); AzureAIAgent agent = new(definition, this.Client); // Create a thread for the agent conversation. diff --git a/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs index 407cae9feb97..1b816a8663ea 100644 --- a/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/Step10_MultiAgent_Declarative.cs @@ -79,7 +79,7 @@ public async Task AzureAIAgentWithKernel() { var azureaiAgent = agent as AzureAIAgent; Assert.NotNull(azureaiAgent); - await azureaiAgent.Client.DeleteAgentAsync(azureaiAgent.Id); + await azureaiAgent.Client.Administration.DeleteAgentAsync(azureaiAgent.Id); if (agentThread is not null) { @@ -97,7 +97,7 @@ public Step10_MultiAgent_Declarative(ITestOutputHelper output) : base(output) OpenAIAssistantAgent.CreateAzureOpenAIClient(new ApiKeyCredential(this.ApiKey), new Uri(this.Endpoint!)) : OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(this.Endpoint!)); - var agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureCliCredential()); + var agentsClient = AzureAIAgent.CreateAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); var builder = Kernel.CreateBuilder(); builder.Services.AddSingleton(openaiClient); diff --git a/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj b/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj index 441878455807..e448a8f4f291 100644 --- a/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj +++ b/dotnet/src/Agents/AzureAI/Agents.AzureAI.csproj @@ -38,7 +38,6 @@ - diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs index d0e9afb773b3..b82b0f0c093a 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.ClientFactory.cs @@ -1,7 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -using System; using System.Net.Http; -using Azure; using Azure.AI.Agents.Persistent; using Azure.Core; using Azure.Core.Pipeline; @@ -14,33 +12,13 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI; /// public sealed partial class AzureAIAgent : Agent { - ///// // %%% REMOVE ME - ///// Produces a . - ///// - ///// The Azure AI Foundry project endpoint. - ///// A credential used to authenticate to an Azure Service. - ///// A custom for HTTP requests. - //public static PersistentAgentsClient CreateAgentsClient( - // string endpoint, - // AzureKeyCredential credential, - // HttpClient? httpClient = null) - //{ - // Verify.NotNull(endpoint, nameof(endpoint)); - // Verify.NotNull(credential, nameof(credential)); - - // PersistentAgentsAdministrationClientOptions clientOptions = CreateAzureClientOptions(httpClient); - - // return new PersistentAgentsClient(endpoint, credential, clientOptions); - //} - /// /// Produces a . /// /// The Azure AI Foundry project endpoint. /// A credential used to authenticate to an Azure Service. /// A custom for HTTP requests. - public static PersistentAgentsClient CreateAgentsClient - ( + public static PersistentAgentsClient CreateAgentsClient( string endpoint, TokenCredential credential, HttpClient? httpClient = null) diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs index bc040335c9c7..c02cff51eab4 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs @@ -430,7 +430,7 @@ protected override async Task RestoreChannelAsync(string channelSt this.Logger.LogAzureAIAgentRestoringChannel(nameof(RestoreChannelAsync), nameof(AzureAIChannel), threadId); - PersistentAgentThread thread = await this.Client.GetThreadAsync(threadId, cancellationToken).ConfigureAwait(false); + PersistentAgentThread thread = await this.Client.Threads.GetThreadAsync(threadId, cancellationToken).ConfigureAwait(false); this.Logger.LogAzureAIAgentRestoredChannel(nameof(RestoreChannelAsync), nameof(AzureAIChannel), threadId); diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs index 4e75b636ff0d..f111a0ca0515 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgentThread.cs @@ -78,7 +78,7 @@ public AzureAIAgentThread(PersistentAgentsClient client, string id) try { - var agentThreadResponse = await this._client.CreateThreadAsync( + var agentThreadResponse = await this._client.Threads.CreateThreadAsync( this._messages, this._toolResources, this._metadata, @@ -102,7 +102,7 @@ protected override async Task DeleteInternalAsync(CancellationToken cancellation try { - await this._client.DeleteThreadAsync(this.Id, cancellationToken).ConfigureAwait(false); + await this._client.Threads.DeleteThreadAsync(this.Id, cancellationToken).ConfigureAwait(false); } catch (RequestFailedException ex) when (ex.Status == 404) { diff --git a/dotnet/src/Agents/AzureAI/AzureAIChannel.cs b/dotnet/src/Agents/AzureAI/AzureAIChannel.cs index 47ba25794a75..e1b57d4ad32b 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIChannel.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIChannel.cs @@ -53,7 +53,7 @@ protected override IAsyncEnumerable GetHistoryAsync(Cancella /// protected override Task ResetAsync(CancellationToken cancellationToken = default) { - return client.DeleteThreadAsync(threadId, cancellationToken); + return client.Threads.DeleteThreadAsync(threadId, cancellationToken); } /// diff --git a/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs b/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs index fd1bea827d52..b7e169af2dbb 100644 --- a/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs +++ b/dotnet/src/Agents/AzureAI/Definition/AzureAIAgentFactory.cs @@ -39,7 +39,7 @@ public AzureAIAgentFactory() if (!string.IsNullOrEmpty(agentDefinition.Id)) { // Get an existing agent - agent = await client.GetAgentAsync( + agent = await client.Administration.GetAgentAsync( agentDefinition.Id, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -56,7 +56,7 @@ public AzureAIAgentFactory() Verify.NotNull(agentDefinition.Model); Verify.NotNull(agentDefinition.Model.Id); - agent = await client.CreateAgentAsync( + agent = await client.Administration.CreateAgentAsync( model: agentDefinition.Model.Id, name: agentDefinition.Name, description: agentDefinition.Description, diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs index 2b80225a6c90..517266c0fc38 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentDefinitionExtensions.cs @@ -230,9 +230,9 @@ private static BingGroundingToolDefinition CreateBingGroundingToolDefinition(Age { Verify.NotNull(tool); - ToolConnectionList bingGrounding = tool.GetToolConnectionList(); + BingGroundingSearchToolParameters bingToolParameters = new(tool.GetToolConnections().Select(connectionId => new BingGroundingSearchConfiguration(connectionId))); - return new BingGroundingToolDefinition(bingGrounding); + return new BingGroundingToolDefinition(bingToolParameters); } private static CodeInterpreterToolDefinition CreateCodeInterpreterToolDefinition(AgentToolDefinition tool) diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs index 57bbc8d92df1..53133baafd07 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentRunExtensions.cs @@ -67,7 +67,8 @@ await client.Runs.CreateRunAsync( private static BinaryData? GetResponseFormat(AzureAIInvocationOptions? invocationOptions) { return invocationOptions?.EnableJsonResponse == true ? - BinaryData.FromString(ResponseFormat.JsonObject.ToString()) : + //BinaryData.FromString(ResponseFormat.JsonObject.ToString()) : + BinaryData.FromString("// %%% TODO") : null; } diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs index c88f897babc1..dfb4c4bb3b87 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs @@ -75,20 +75,6 @@ internal static FileSearchToolDefinitionDetails GetFileSearchToolDefinitionDetai return details; } - internal static ToolConnectionList GetToolConnectionList(this AgentToolDefinition agentToolDefinition) - { - Verify.NotNull(agentToolDefinition.Options); - - var toolConnections = agentToolDefinition.GetToolConnections(); - - var toolConnectionList = new ToolConnectionList(); - if (toolConnections is not null) - { - toolConnectionList.ConnectionList.AddRange(toolConnections); - } - return toolConnectionList; - } - internal static BinaryData GetSpecification(this AgentToolDefinition agentToolDefinition) { Verify.NotNull(agentToolDefinition.Options); @@ -236,13 +222,13 @@ private static AzureFunctionBinding GetAzureFunctionBinding(this AgentToolDefini return null; } - private static List GetToolConnections(this AgentToolDefinition agentToolDefinition) + internal static List GetToolConnections(this AgentToolDefinition agentToolDefinition) { Verify.NotNull(agentToolDefinition.Options); - var toolConnections = agentToolDefinition.GetRequiredOption>("tool_connections"); + List toolConnections = agentToolDefinition.GetRequiredOption>("tool_connections"); - return toolConnections.Select(connectionId => new ToolConnection(connectionId.ToString())).ToList(); + return [.. toolConnections.Select(connectionId => $"{connectionId}")]; } private static T GetRequiredOption(this AgentToolDefinition agentToolDefinition, string key) diff --git a/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs b/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs index 30fa96ba2024..7be5906ec5c6 100644 --- a/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs +++ b/dotnet/src/Agents/AzureAI/Internal/AgentMessageFactory.cs @@ -15,7 +15,7 @@ namespace Microsoft.SemanticKernel.Agents.AzureAI.Internal; internal static class AgentMessageFactory { /// - /// Translate metadata from a to be used for a or + /// Translate metadata from a to be used for a or /// . /// /// The message content. @@ -25,7 +25,7 @@ public static Dictionary GetMetadata(ChatMessageContent message) } /// - /// Translate attachments from a to be used for a or + /// Translate attachments from a to be used for a or /// /// The message content. public static IEnumerable GetAttachments(ChatMessageContent message) diff --git a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs index 0ef4043e26e4..d0aa27fa1d38 100644 --- a/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs +++ b/dotnet/src/Agents/UnitTests/AzureAI/Definition/AzureAIAgentFactoryTests.cs @@ -33,9 +33,9 @@ public AzureAIAgentFactoryTests() var builder = Kernel.CreateBuilder(); var client = new PersistentAgentsClient( - new Uri("https://test"), + "https://test", new FakeTokenCredential(), - new PersistentAgentsClientOptions + new PersistentAgentsAdministrationClientOptions { Transport = new HttpClientTransport(this._httpClient) }); diff --git a/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs b/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs index db79cc9ea366..e7c23cce73db 100644 --- a/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs +++ b/dotnet/src/Agents/UnitTests/Yaml/AgentYamlTests.cs @@ -44,9 +44,9 @@ public AgentYamlTests() // Add Azure AI agents client var client = new PersistentAgentsClient( - new Uri("https://endpoint"), + "https://endpoint", new FakeTokenCredential(), - new PersistentAgentsClientOptions + new PersistentAgentsAdministrationClientOptions { Transport = new HttpClientTransport(this._httpClient) }); diff --git a/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs b/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs index 016ca6148596..ea0fef2986c0 100644 --- a/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs +++ b/dotnet/src/Agents/UnitTests/Yaml/AzureAIKernelAgentYamlTests.cs @@ -39,9 +39,9 @@ public AzureAIKernelAgentYamlTests() // Add Azure AI agents client var client = new PersistentAgentsClient( - new Uri("https://test"), + "https://test", new FakeTokenCredential(), - new PersistentAgentsClientOptions + new PersistentAgentsAdministrationClientOptions { Transport = new HttpClientTransport(this._httpClient) }); @@ -219,42 +219,6 @@ public async Task VerifyRequestIncludesBingGroundingAsync() Assert.Equal("bing_grounding", requestJson.GetProperty("tools")[0].GetProperty("type").GetString()); } - /// - /// Verify the request includes a Microsoft Fabric tool when creating an Azure AI agent. - /// - [Fact] - public async Task VerifyRequestIncludesMicrosoftFabricAsync() - { - // Arrange - const string Text = - """ - type: foundry_agent - name: FoundryAgent - description: AzureAIAgent Description - instructions: AzureAIAgent Instructions - model: - id: gpt-4o-mini - tools: - - type: fabric_aiskill - options: - tool_connections: - - connection_string - """; - AzureAIAgentFactory factory = new(); - this.SetupResponse(HttpStatusCode.OK, AzureAIAgentFactoryTests.AzureAIAgentCreateResponse); - - // Act - var agent = await factory.CreateAgentFromYamlAsync(Text, new() { Kernel = this._kernel }); - - // Assert - Assert.NotNull(agent); - var requestContent = Encoding.UTF8.GetString(this._messageHandlerStub.RequestContent!); - Assert.NotNull(requestContent); - var requestJson = JsonSerializer.Deserialize(requestContent); - Assert.Equal(1, requestJson.GetProperty("tools").GetArrayLength()); - Assert.Equal("fabric_dataagent", requestJson.GetProperty("tools")[0].GetProperty("type").GetString()); - } - /// /// Verify the request includes a Open API tool when creating an Azure AI agent. /// @@ -308,42 +272,6 @@ public async Task VerifyRequestIncludesOpenAPIAsync() Assert.Equal("openapi", requestJson.GetProperty("tools")[2].GetProperty("type").GetString()); } - /// - /// Verify the request includes a Sharepoint tool when creating an Azure AI agent. - /// - [Fact] - public async Task VerifyRequestIncludesSharepointGroundingAsync() - { - // Arrange - const string Text = - """ - type: foundry_agent - name: FoundryAgent - description: AzureAIAgent Description - instructions: AzureAIAgent Instructions - model: - id: gpt-4o-mini - tools: - - type: sharepoint_grounding - options: - tool_connections: - - connection_string - """; - AzureAIAgentFactory factory = new(); - this.SetupResponse(HttpStatusCode.OK, AzureAIAgentFactoryTests.AzureAIAgentCreateResponse); - - // Act - var agent = await factory.CreateAgentFromYamlAsync(Text, new() { Kernel = this._kernel }); - - // Assert - Assert.NotNull(agent); - var requestContent = Encoding.UTF8.GetString(this._messageHandlerStub.RequestContent!); - Assert.NotNull(requestContent); - var requestJson = JsonSerializer.Deserialize(requestContent); - Assert.Equal(1, requestJson.GetProperty("tools").GetArrayLength()); - Assert.Equal("sharepoint_grounding", requestJson.GetProperty("tools")[0].GetProperty("type").GetString()); - } - /// /// Verify the request includes a code interpreter tool and associated resource when creating an Azure AI agent. /// diff --git a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs index 4b4e0c49009e..6fabcf07dbc6 100644 --- a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading.Tasks; using Azure.AI.Agents.Persistent; -using Azure.AI.Projects; using Azure.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -30,7 +29,7 @@ public AzureAIAgentTests() var kernelBuilder = Kernel.CreateBuilder(); this._kernel = kernelBuilder.Build(); this._configuration = this.ReadAzureConfiguration(); - this._client = AzureAIAgent.CreateAgentsClient(new Uri(this._configuration.Endpoint), new AzureCliCredential()); + this._client = AzureAIAgent.CreateAgentsClient(this._configuration.Endpoint, new AzureCliCredential()); } /// @@ -40,7 +39,7 @@ public AzureAIAgentTests() public async Task AzureAIAgentWithThreadCustomOptionsAsync() { var aiAgent = - await this._client.CreateAgentAsync( + await this._client.Administration.CreateAgentAsync( this._configuration.ChatModelId, name: "HelpfulAssistant", description: "Helpful Assistant", @@ -63,7 +62,7 @@ await this._client.CreateAgentAsync( finally { await agentThread.DeleteAsync(); - await this._client.DeleteAgentAsync(agent.Id); + await this._client.Administration.DeleteAgentAsync(agent.Id); } } @@ -74,7 +73,7 @@ await this._client.CreateAgentAsync( public async Task AzureAIAgentWithThreadCustomOptionsStreamingAsync() { var aiAgent = - await this._client.CreateAgentAsync( + await this._client.Administration.CreateAgentAsync( this._configuration.ChatModelId, name: "HelpfulAssistant", description: "Helpful Assistant", @@ -97,7 +96,7 @@ await this._client.CreateAgentAsync( finally { await agentThread.DeleteAsync(); - await this._client.DeleteAgentAsync(agent.Id); + await this._client.Administration.DeleteAgentAsync(agent.Id); } } @@ -135,7 +134,7 @@ public async Task AzureAIAgentDeclarativeAsync() finally { await agentThread.DeleteAsync(); - await this._client.DeleteAgentAsync(agent.Id); + await this._client.Administration.DeleteAgentAsync(agent.Id); } } diff --git a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs index 64db43c3d6c4..7c64a525b3fb 100644 --- a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs +++ b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/AzureAIAgentFixture.cs @@ -53,7 +53,7 @@ public override async Task GetChatHistory() public override Task DeleteThread(AgentThread thread) { - return this._agentsClient!.DeleteThreadAsync(thread.Id); + return this._agentsClient!.Threads.DeleteThreadAsync(thread.Id); } public override async Task DisposeAsync() @@ -62,7 +62,7 @@ public override async Task DisposeAsync() { try { - await this._agentsClient!.DeleteThreadAsync(this._thread!.Id); + await this._agentsClient!.Threads.DeleteThreadAsync(this._thread!.Id); } catch (RequestFailedException ex) when (ex.Status == 404) { @@ -71,7 +71,7 @@ public override async Task DisposeAsync() try { - await this._agentsClient!.DeleteThreadAsync(this._createdThread!.Id); + await this._agentsClient!.Threads.DeleteThreadAsync(this._createdThread!.Id); } catch (RequestFailedException ex) when (ex.Status == 404) { @@ -79,22 +79,22 @@ public override async Task DisposeAsync() try { - await this._agentsClient!.DeleteThreadAsync(this._createdServiceFailingAgentThread!.Id); + await this._agentsClient!.Threads.DeleteThreadAsync(this._createdServiceFailingAgentThread!.Id); } catch (RequestFailedException ex) when (ex.Status == 404) { } - await this._agentsClient!.DeleteAgentAsync(this._aiAgent!.Id); + await this._agentsClient!.Administration.DeleteAgentAsync(this._aiAgent!.Id); } public override async Task InitializeAsync() { AzureAIConfiguration configuration = this._configuration.GetSection("AzureAI").Get()!; - this._agentsClient = AzureAIAgent.CreateAgentsClient(new Uri(configuration.Endpoint), new AzureCliCredential()); + this._agentsClient = AzureAIAgent.CreateAgentsClient(configuration.Endpoint, new AzureCliCredential()); this._aiAgent = - await this._agentsClient.CreateAgentAsync( + await this._agentsClient.Administration.CreateAgentAsync( configuration.ChatModelId, name: "HelpfulAssistant", description: "Helpful Assistant", @@ -109,10 +109,10 @@ await this._agentsClient.CreateAgentAsync( this._createdThread = new AzureAIAgentThread(this._agentsClient); await this._createdThread.CreateAsync(); - var serviceFailingClient = AzureAIAgent.CreateAgentsClient(new Uri("https://invalid"), new AzureCliCredential()); + var serviceFailingClient = AzureAIAgent.CreateAgentsClient("https://invalid", new AzureCliCredential()); this._serviceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient); - var createdFailingThreadResponse = await this._agentsClient.CreateThreadAsync(); + var createdFailingThreadResponse = await this._agentsClient.Threads.CreateThreadAsync(); this._createdServiceFailingAgentThread = new AzureAIAgentThread(serviceFailingClient, createdFailingThreadResponse.Value.Id); } } diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs index f76cee85de92..0c4c3608b1b3 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using Azure; using Azure.AI.Agents.Persistent; -using Azure.AI.Projects.OneDP; using Azure.Identity; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; @@ -21,11 +20,6 @@ protected BaseAzureAgentTest(ITestOutputHelper output) : base(output) protected override PersistentAgentsClient Client { get; } - protected AIProjectClient CreateProjectClient() => - string.IsNullOrEmpty(TestConfiguration.AzureAI.ApiKey) ? - new AIProjectClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureCliCredential()) : - new AIProjectClient(new Uri(TestConfiguration.AzureAI.Endpoint), new AzureKeyCredential(TestConfiguration.AzureAI.ApiKey)); - protected async Task DownloadContentAsync(ChatMessageContent message) { foreach (KernelContent item in message.Items) From ac4d84e31aa0173afcf9c86f43744e9c140695a8 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 15 May 2025 19:11:13 -0700 Subject: [PATCH 13/20] Namespace --- .../InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs index 0c4c3608b1b3..c2b80ffa3e78 100644 --- a/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs +++ b/dotnet/src/InternalUtilities/samples/AgentUtilities/BaseAzureTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using System.Diagnostics; -using Azure; using Azure.AI.Agents.Persistent; using Azure.Identity; using Microsoft.SemanticKernel; From 1a3ce3a19f9c2e62294152d821877112c21517ea Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 15 May 2025 20:37:06 -0700 Subject: [PATCH 14/20] Cleanup --- .../AzureAIAgent/Step03_AzureAIAgent_Chat.cs | 2 ++ .../AzureAIAgent/Step08_AzureAIAgent_Declarative.cs | 3 --- .../Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs | 2 +- dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs index 0f9a7a9823f2..18a5b71fffd7 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs @@ -88,6 +88,8 @@ public async Task UseGroupChatWithTwoAgents() } finally { + await agentReviewer.Client.Administration.DeleteAgentAsync(agentReviewer.Id); + await agentWriter.Client.Administration.DeleteAgentAsync(agentWriter.Id); await chat.ResetAsync(); } } diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs index 62cc2685f435..7a50dcf0475b 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step08_AzureAIAgent_Declarative.cs @@ -191,9 +191,6 @@ public async Task AzureAIAgentWithFileSearch() """; AzureAIAgentFactory factory = new(); - KernelPlugin plugin = KernelPluginFactory.CreateFromType(); - this._kernel.Plugins.Add(plugin); - var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "What are the key features of the Semantic Kernel?"); diff --git a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs index dfb4c4bb3b87..053c8dc52ffd 100644 --- a/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs +++ b/dotnet/src/Agents/AzureAI/Extensions/AgentToolDefinitionExtensions.cs @@ -107,7 +107,7 @@ internal static OpenApiAuthDetails GetOpenApiAuthDetails(this AgentToolDefinitio internal static List? GetVectorStoreIds(this AgentToolDefinition agentToolDefinition) { - return agentToolDefinition.GetOption>("vector_store_ids")?.Select(id => id.ToString()!).ToList(); + return agentToolDefinition.GetOption>("vector_store_ids")?.Select(id => $"{id}").ToList(); } internal static List? GetFileIds(this AgentToolDefinition agentToolDefinition) diff --git a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs index 6fabcf07dbc6..abbb9caed362 100644 --- a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All rights reserved. -using System; using System.Linq; using System.Threading.Tasks; using Azure.AI.Agents.Persistent; From 5c0a1d963d6f486c9e60c645f7740d02e5a282cd Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 15 May 2025 23:55:50 -0700 Subject: [PATCH 15/20] Update foundry processes --- .../Step06/Step06_FoundryAgentProcess.cs | 8 ++------ .../Process.Abstractions/Process.Abstractions.csproj | 1 - .../Process.LocalRuntime/Process.LocalRuntime.csproj | 1 - .../process/Runtime/AgentThreadFactory.cs | 4 ++-- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs index a2909f7d0380..43f24a265527 100644 --- a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs +++ b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs @@ -44,12 +44,10 @@ public async Task ProcessWithExistingFoundryAgentsAndSeparateThreadsAsync() var process = processBuilder.Build(); - var foundryClient = AzureAIAgent.CreateAzureAIClient(TestConfiguration.AzureAI.ConnectionString, new AzureCliCredential()); - var agentsClient = foundryClient.GetAgentsClient(); + var agentsClient = AzureAIAgent.CreateAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); var kernelBuilder = Kernel.CreateBuilder(); kernelBuilder.Services.AddSingleton(agentsClient); - kernelBuilder.Services.AddSingleton(foundryClient); var kernel = kernelBuilder.Build(); var context = await process.StartAsync(kernel, new() { Id = "start", Data = "What is the best programming language and why?" }); @@ -78,12 +76,10 @@ public async Task ProcessWithExistingFoundryAgentsAndSharedThreadAsync() var process = processBuilder.Build(); - var foundryClient = AzureAIAgent.CreateAzureAIClient(TestConfiguration.AzureAI.ConnectionString, new AzureCliCredential()); - var agentsClient = foundryClient.GetAgentsClient(); + var agentsClient = AzureAIAgent.CreateAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential()); var kernelBuilder = Kernel.CreateBuilder(); kernelBuilder.Services.AddSingleton(agentsClient); - kernelBuilder.Services.AddSingleton(foundryClient); var kernel = kernelBuilder.Build(); var context = await process.StartAsync(kernel, new() { Id = "start", Data = "Why are frogs green?" }); diff --git a/dotnet/src/Experimental/Process.Abstractions/Process.Abstractions.csproj b/dotnet/src/Experimental/Process.Abstractions/Process.Abstractions.csproj index 82ceb5372f15..f4af8d637107 100644 --- a/dotnet/src/Experimental/Process.Abstractions/Process.Abstractions.csproj +++ b/dotnet/src/Experimental/Process.Abstractions/Process.Abstractions.csproj @@ -40,7 +40,6 @@ - diff --git a/dotnet/src/Experimental/Process.LocalRuntime/Process.LocalRuntime.csproj b/dotnet/src/Experimental/Process.LocalRuntime/Process.LocalRuntime.csproj index d5f245549da4..270e25bf7421 100644 --- a/dotnet/src/Experimental/Process.LocalRuntime/Process.LocalRuntime.csproj +++ b/dotnet/src/Experimental/Process.LocalRuntime/Process.LocalRuntime.csproj @@ -41,7 +41,6 @@ - diff --git a/dotnet/src/InternalUtilities/process/Runtime/AgentThreadFactory.cs b/dotnet/src/InternalUtilities/process/Runtime/AgentThreadFactory.cs index 51b616e8ea33..856c233570a0 100644 --- a/dotnet/src/InternalUtilities/process/Runtime/AgentThreadFactory.cs +++ b/dotnet/src/InternalUtilities/process/Runtime/AgentThreadFactory.cs @@ -39,13 +39,13 @@ public static async Task CreateAgentThreadAsync(this KernelProcessA private static async Task CreateAzureAIThreadAsync(string? id, Kernel kernel) { const string ErrorMessage = "The thread could not be created due to an error response from the service."; - var client = kernel.Services.GetService() ?? throw new KernelException("The AzureAI thread type requires an AgentsClient to be registered in the kernel."); + var client = kernel.Services.GetService() ?? throw new KernelException("The AzureAI thread type requires an AgentsClient to be registered in the kernel."); if (string.IsNullOrWhiteSpace(id)) { try { - var threadResponse = await client.CreateThreadAsync().ConfigureAwait(false); + var threadResponse = await client.Threads.CreateThreadAsync().ConfigureAwait(false); id = threadResponse.Value.Id; } catch (RequestFailedException ex) From 1285909e0753059b6bfcf5438fc466cb7accf832 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 15 May 2025 23:58:35 -0700 Subject: [PATCH 16/20] Trigger build --- .../samples/InternalUtilities/TestConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs b/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs index bf12bf0bf05d..009149a9b961 100644 --- a/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs +++ b/dotnet/src/InternalUtilities/samples/InternalUtilities/TestConfiguration.cs @@ -106,9 +106,9 @@ public class OnnxConfig public class AzureAIConfig { + public string ChatModelId { get; set; } public string Endpoint { get; set; } public string WorkflowEndpoint { get; set; } - public string ChatModelId { get; set; } public string BingConnectionId { get; set; } public string VectorStoreId { get; set; } public string AgentId { get; set; } From c5144cb4c503154b055f01db8f1788d8e625db21 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Fri, 16 May 2025 10:19:07 -0700 Subject: [PATCH 17/20] Sample hygiene --- .../Concepts/Agents/AzureAIAgent_Streaming.cs | 59 +++++++++++++------ .../AzureAIAgent/Step03_AzureAIAgent_Chat.cs | 2 +- .../GettingStartedWithAgents/Step03_Chat.cs | 25 +++++--- .../Step06/Step06_FoundryAgentProcess.cs | 27 +++++---- 4 files changed, 74 insertions(+), 39 deletions(-) diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs index 62b1ee5ed86c..e01e30f663c3 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_Streaming.cs @@ -27,16 +27,23 @@ public async Task UseStreamingAgentAsync() AgentInstructions); AzureAIAgent agent = new(definition, this.Client); - // Create a thread for the agent conversation. - AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); + try + { + // Create a thread for the agent conversation. + AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); - // Respond to user input - await InvokeAgentAsync(agent, agentThread, "Fortune favors the bold."); - await InvokeAgentAsync(agent, agentThread, "I came, I saw, I conquered."); - await InvokeAgentAsync(agent, agentThread, "Practice makes perfect."); + // Respond to user input + await InvokeAgentAsync(agent, agentThread, "Fortune favors the bold."); + await InvokeAgentAsync(agent, agentThread, "I came, I saw, I conquered."); + await InvokeAgentAsync(agent, agentThread, "Practice makes perfect."); - // Output the entire chat history - await DisplayChatHistoryAsync(agentThread); + // Output the entire chat history + await DisplayChatHistoryAsync(agentThread); + } + finally + { + await this.Client.Administration.DeleteAgentAsync(agent.Id); + } } [Fact] @@ -60,12 +67,20 @@ public async Task UseStreamingAssistantAgentWithPluginAsync() // Create a thread for the agent conversation. AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); - // Respond to user input - await InvokeAgentAsync(agent, agentThread, "What is the special soup and its price?"); - await InvokeAgentAsync(agent, agentThread, "What is the special drink and its price?"); + try + { + // Respond to user input + await InvokeAgentAsync(agent, agentThread, "What is the special soup and its price?"); + await InvokeAgentAsync(agent, agentThread, "What is the special drink and its price?"); - // Output the entire chat history - await DisplayChatHistoryAsync(agentThread); + // Output the entire chat history + await DisplayChatHistoryAsync(agentThread); + } + finally + { + await this.Client.Threads.DeleteThreadAsync(agentThread.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); + } } [Fact] @@ -86,12 +101,20 @@ public async Task UseStreamingAssistantWithCodeInterpreterAsync() // Create a thread for the agent conversation. AzureAIAgentThread agentThread = new(this.Client, metadata: SampleMetadata); - // Respond to user input - await InvokeAgentAsync(agent, agentThread, "Is 191 a prime number?"); - await InvokeAgentAsync(agent, agentThread, "Determine the values in the Fibonacci sequence that that are less then the value of 101"); + try + { + // Respond to user input + await InvokeAgentAsync(agent, agentThread, "Is 191 a prime number?"); + await InvokeAgentAsync(agent, agentThread, "Determine the values in the Fibonacci sequence that that are less then the value of 101"); - // Output the entire chat history - await DisplayChatHistoryAsync(agentThread); + // Output the entire chat history + await DisplayChatHistoryAsync(agentThread); + } + finally + { + await this.Client.Threads.DeleteThreadAsync(agentThread.Id); + await this.Client.Administration.DeleteAgentAsync(agent.Id); + } } // Local function to invoke agent and display the conversation messages. diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs index 18a5b71fffd7..654ea1d9bfd0 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step03_AzureAIAgent_Chat.cs @@ -88,9 +88,9 @@ public async Task UseGroupChatWithTwoAgents() } finally { + await chat.ResetAsync(); await agentReviewer.Client.Administration.DeleteAgentAsync(agentReviewer.Id); await agentWriter.Client.Administration.DeleteAgentAsync(agentWriter.Id); - await chat.ResetAsync(); } } diff --git a/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs b/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs index 637151780ee2..afe3f0b120fb 100644 --- a/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs @@ -73,17 +73,26 @@ public async Task UseAgentGroupChatWithTwoAgents() } }; - // Invoke chat and display messages. - ChatMessageContent input = new(AuthorRole.User, "concept: maps made out of egg cartons."); - chat.AddChatMessage(input); - this.WriteAgentChatMessage(input); + try + { + // Invoke chat and display messages. + ChatMessageContent input = new(AuthorRole.User, "concept: maps made out of egg cartons."); + chat.AddChatMessage(input); + this.WriteAgentChatMessage(input); + + await foreach (ChatMessageContent response in chat.InvokeAsync()) + { + this.WriteAgentChatMessage(response); + } - await foreach (ChatMessageContent response in chat.InvokeAsync()) + Console.WriteLine($"\n[IS COMPLETED: {chat.IsComplete}]"); + } + finally { - this.WriteAgentChatMessage(response); + await chat.ResetAsync(); + await agentReviewer.Client.Administration.DeleteAgentAsync(agentReviewer.Id); + await agentWriter.Client.Administration.DeleteAgentAsync(agentWriter.Id); } - - Console.WriteLine($"\n[IS COMPLETED: {chat.IsComplete}]"); } private sealed class ApprovalTerminationStrategy : TerminationStrategy diff --git a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs index 43f24a265527..6c4c56f008e4 100644 --- a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs +++ b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs @@ -12,6 +12,9 @@ namespace Step06; public class Step06_FoundryAgentProcess : BaseTest { + private const string Agent1Id = "asst_aAsLEzwbFDMDcyQl70pLqVi0"; + private const string Agent2Id = "asst_DGvpjCuKdbNF81Ku2XdQPX7F"; + public Step06_FoundryAgentProcess(ITestOutputHelper output) : base(output, redirectSystemConsoleOutput: true) { this.Client = @@ -30,8 +33,8 @@ public Step06_FoundryAgentProcess(ITestOutputHelper output) : base(output, redir [Fact] public async Task ProcessWithExistingFoundryAgentsAndSeparateThreadsAsync() { - var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -60,8 +63,8 @@ public async Task ProcessWithExistingFoundryAgentsAndSeparateThreadsAsync() [Fact] public async Task ProcessWithExistingFoundryAgentsAndSharedThreadAsync() { - var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -93,8 +96,8 @@ public async Task ProcessWithExistingFoundryAgentsAndSharedThreadAsync() public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOnCompleteConditions() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -115,8 +118,8 @@ public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOnCom public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOrchestrationConditions() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -148,7 +151,7 @@ public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOrche public async Task ProcessWithExistingFoundryAgentsWithDynamicAgentResolution() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; var foundryAgentDefinition2 = new AgentDefinition { Id = "_variables_.NextAgentId", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type @@ -181,8 +184,8 @@ public async Task ProcessWithExistingFoundryAgentsWithDynamicAgentResolution() public async Task ProcessWithTwoAgentMathChat() { // Define the agents - var studentDefinition = new AgentDefinition { Id = "{AGENT_ID}", Name = "Student", Type = AzureAIAgentFactory.AzureAIAgentType }; - var teacherDefinition = new AgentDefinition { Id = "{AGENT_ID2}", Name = "Teacher", Type = AzureAIAgentFactory.AzureAIAgentType }; + var studentDefinition = new AgentDefinition { Id = Agent1Id, Name = "Student", Type = AzureAIAgentFactory.AzureAIAgentType }; + var teacherDefinition = new AgentDefinition { Id = Agent2Id, Name = "Teacher", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("two_agent_math_chat"); @@ -258,7 +261,7 @@ public class StudentState public class DynamicAgentState { - public string NextAgentId { get; set; } = "{AGENT_ID}"; + public string NextAgentId { get; set; } = Agent2Id; public int Counter { get; set; } } From 3019c34aff5ad2b9a43be4301b98911e4d92688b Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Fri, 16 May 2025 10:33:45 -0700 Subject: [PATCH 18/20] Rollback Step06 testing edits --- .../GettingStartedWithAgents/Step03_Chat.cs | 25 ++++++----------- .../Step06/Step06_FoundryAgentProcess.cs | 27 +++++++++---------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs b/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs index afe3f0b120fb..637151780ee2 100644 --- a/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs +++ b/dotnet/samples/GettingStartedWithAgents/Step03_Chat.cs @@ -73,26 +73,17 @@ public async Task UseAgentGroupChatWithTwoAgents() } }; - try - { - // Invoke chat and display messages. - ChatMessageContent input = new(AuthorRole.User, "concept: maps made out of egg cartons."); - chat.AddChatMessage(input); - this.WriteAgentChatMessage(input); - - await foreach (ChatMessageContent response in chat.InvokeAsync()) - { - this.WriteAgentChatMessage(response); - } + // Invoke chat and display messages. + ChatMessageContent input = new(AuthorRole.User, "concept: maps made out of egg cartons."); + chat.AddChatMessage(input); + this.WriteAgentChatMessage(input); - Console.WriteLine($"\n[IS COMPLETED: {chat.IsComplete}]"); - } - finally + await foreach (ChatMessageContent response in chat.InvokeAsync()) { - await chat.ResetAsync(); - await agentReviewer.Client.Administration.DeleteAgentAsync(agentReviewer.Id); - await agentWriter.Client.Administration.DeleteAgentAsync(agentWriter.Id); + this.WriteAgentChatMessage(response); } + + Console.WriteLine($"\n[IS COMPLETED: {chat.IsComplete}]"); } private sealed class ApprovalTerminationStrategy : TerminationStrategy diff --git a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs index 6c4c56f008e4..43f24a265527 100644 --- a/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs +++ b/dotnet/samples/GettingStartedWithProcesses/Step06/Step06_FoundryAgentProcess.cs @@ -12,9 +12,6 @@ namespace Step06; public class Step06_FoundryAgentProcess : BaseTest { - private const string Agent1Id = "asst_aAsLEzwbFDMDcyQl70pLqVi0"; - private const string Agent2Id = "asst_DGvpjCuKdbNF81Ku2XdQPX7F"; - public Step06_FoundryAgentProcess(ITestOutputHelper output) : base(output, redirectSystemConsoleOutput: true) { this.Client = @@ -33,8 +30,8 @@ public Step06_FoundryAgentProcess(ITestOutputHelper output) : base(output, redir [Fact] public async Task ProcessWithExistingFoundryAgentsAndSeparateThreadsAsync() { - var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -63,8 +60,8 @@ public async Task ProcessWithExistingFoundryAgentsAndSeparateThreadsAsync() [Fact] public async Task ProcessWithExistingFoundryAgentsAndSharedThreadAsync() { - var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -96,8 +93,8 @@ public async Task ProcessWithExistingFoundryAgentsAndSharedThreadAsync() public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOnCompleteConditions() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -118,8 +115,8 @@ public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOnCom public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOrchestrationConditions() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; - var foundryAgentDefinition2 = new AgentDefinition { Id = Agent2Id, Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition2 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("foundry_agents"); @@ -151,7 +148,7 @@ public async Task ProcessWithExistingFoundryAgentsWithProcessStateUpdateAndOrche public async Task ProcessWithExistingFoundryAgentsWithDynamicAgentResolution() { // Define the agents - var foundryAgentDefinition1 = new AgentDefinition { Id = Agent1Id, Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; + var foundryAgentDefinition1 = new AgentDefinition { Id = "{AGENT_ID}", Name = "Agent1", Type = AzureAIAgentFactory.AzureAIAgentType }; var foundryAgentDefinition2 = new AgentDefinition { Id = "_variables_.NextAgentId", Name = "Agent2", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type @@ -184,8 +181,8 @@ public async Task ProcessWithExistingFoundryAgentsWithDynamicAgentResolution() public async Task ProcessWithTwoAgentMathChat() { // Define the agents - var studentDefinition = new AgentDefinition { Id = Agent1Id, Name = "Student", Type = AzureAIAgentFactory.AzureAIAgentType }; - var teacherDefinition = new AgentDefinition { Id = Agent2Id, Name = "Teacher", Type = AzureAIAgentFactory.AzureAIAgentType }; + var studentDefinition = new AgentDefinition { Id = "{AGENT_ID}", Name = "Student", Type = AzureAIAgentFactory.AzureAIAgentType }; + var teacherDefinition = new AgentDefinition { Id = "{AGENT_ID2}", Name = "Teacher", Type = AzureAIAgentFactory.AzureAIAgentType }; // Define the process with a state type var processBuilder = new FoundryProcessBuilder("two_agent_math_chat"); @@ -261,7 +258,7 @@ public class StudentState public class DynamicAgentState { - public string NextAgentId { get; set; } = Agent2Id; + public string NextAgentId { get; set; } = "{AGENT_ID}"; public int Counter { get; set; } } From a04b83fd113146ab1873828ce8dc36d78a727b8a Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Fri, 16 May 2025 11:54:11 -0700 Subject: [PATCH 19/20] Update assistant test figure configuration --- .../CommonInterfaceConformance/OpenAIAssistantAgentFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/OpenAIAssistantAgentFixture.cs b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/OpenAIAssistantAgentFixture.cs index 4c512e559379..5c23cad1a515 100644 --- a/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/OpenAIAssistantAgentFixture.cs +++ b/dotnet/src/IntegrationTests/Agents/CommonInterfaceConformance/OpenAIAssistantAgentFixture.cs @@ -85,7 +85,7 @@ public override Task DeleteThread(AgentThread thread) public override async Task InitializeAsync() { - AzureAIConfiguration configuration = this._configuration.GetSection("AzureAI").Get()!; + AzureOpenAIConfiguration configuration = this._configuration.GetSection("AzureOpenAI").Get()!; var client = OpenAIAssistantAgent.CreateAzureOpenAIClient(new AzureCliCredential(), new Uri(configuration.Endpoint)); this._assistantClient = client.GetAssistantClient(); From d255a3b8f3b5ddcfb2d5c686998e0c4bb088401c Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Fri, 16 May 2025 16:56:18 -0700 Subject: [PATCH 20/20] Update --- dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs | 3 ++- .../src/IntegrationTests/TestSettings/AzureAIConfiguration.cs | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs index abbb9caed362..49209ac7a9a5 100644 --- a/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs +++ b/dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Linq; using System.Threading.Tasks; using Azure.AI.Agents.Persistent; @@ -88,7 +89,7 @@ await this._client.Administration.CreateAgentAsync( message, agentThread, new AzureAIAgentInvokeOptions() { OverrideInstructions = "Respond to all user questions with 'Computer says no'." }).ToArrayAsync(); - var responseText = string.Join(string.Empty, responseMessages.Select(x => x.Message.Content)); + var responseText = string.Join(Environment.NewLine, responseMessages.Select(x => x.Message.Content)); Assert.Contains("Computer says no", responseText); } diff --git a/dotnet/src/IntegrationTests/TestSettings/AzureAIConfiguration.cs b/dotnet/src/IntegrationTests/TestSettings/AzureAIConfiguration.cs index c89b7824f0d2..d62372d33df9 100644 --- a/dotnet/src/IntegrationTests/TestSettings/AzureAIConfiguration.cs +++ b/dotnet/src/IntegrationTests/TestSettings/AzureAIConfiguration.cs @@ -6,11 +6,9 @@ namespace SemanticKernel.IntegrationTests.TestSettings; [SuppressMessage("Performance", "CA1812:Internal class that is apparently never instantiated", Justification = "Configuration classes are instantiated through IConfiguration.")] -internal sealed class AzureAIConfiguration(string endpoint, string connectionString, string chatModelId) +internal sealed class AzureAIConfiguration(string endpoint, string chatModelId) { public string Endpoint { get; set; } = endpoint; - public string ConnectionString { get; set; } = connectionString; - public string ChatModelId { get; set; } = chatModelId; }