From 026dc1dd402c0b1c77425b4640a62941769925e8 Mon Sep 17 00:00:00 2001 From: westey <164392973+westey-m@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:37:15 +0000 Subject: [PATCH] .Net: Removing groupchat from samples that have a single agent and aren't demonstrating a groupchat concept (#11261) ### Motivation and Context Addressing Feedback from bugbash ### Description Removing groupchat from samples that have a single agent and aren't demonstrating a groupchat concept ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com> --- .../Agents/AzureAIAgent_FileManipulation.cs | 10 +- .../ChatCompletion_FunctionTermination.cs | 94 ------------------- .../Agents/ChatCompletion_HistoryReducer.cs | 68 -------------- .../Agents/OpenAIAssistant_ChartMaker.cs | 14 ++- .../OpenAIAssistant_FileManipulation.cs | 14 ++- .../Agents/OpenAIAssistant_FunctionFilters.cs | 20 ++-- 6 files changed, 29 insertions(+), 191 deletions(-) diff --git a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs index cf55801420df..120af824229c 100644 --- a/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs +++ b/dotnet/samples/Concepts/Agents/AzureAIAgent_FileManipulation.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using Azure.AI.Projects; using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.AzureAI; using Microsoft.SemanticKernel.ChatCompletion; using Resources; @@ -33,9 +32,7 @@ public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() } }); AzureAIAgent agent = new(definition, this.AgentsClient); - - // Create a chat for agent interaction. - AgentGroupChat chat = new(); + AzureAIAgentThread thread = new(this.AgentsClient); // Respond to user input try @@ -46,19 +43,18 @@ public async Task AnalyzeCSVFileUsingAzureAIAgentAsync() } finally { + await thread.DeleteAsync(); await this.AgentsClient.DeleteAgentAsync(agent.Id); await this.AgentsClient.DeleteFileAsync(fileInfo.Id); - await chat.ResetAsync(); } // Local function to invoke agent and display the conversation messages. async Task InvokeAgentAsync(string input) { ChatMessageContent message = new(AuthorRole.User, input); - chat.AddChatMessage(new(AuthorRole.User, input)); this.WriteAgentChatMessage(message); - await foreach (ChatMessageContent response in chat.InvokeAsync(agent)) + await foreach (ChatMessageContent response in agent.InvokeAsync(message, thread)) { this.WriteAgentChatMessage(response); await this.DownloadContentAsync(response); diff --git a/dotnet/samples/Concepts/Agents/ChatCompletion_FunctionTermination.cs b/dotnet/samples/Concepts/Agents/ChatCompletion_FunctionTermination.cs index 0aea67e8f806..0a7960e743c6 100644 --- a/dotnet/samples/Concepts/Agents/ChatCompletion_FunctionTermination.cs +++ b/dotnet/samples/Concepts/Agents/ChatCompletion_FunctionTermination.cs @@ -53,47 +53,6 @@ async Task InvokeAgentAsync(string input) } } - [Fact] - public async Task UseAutoFunctionInvocationFilterWithAgentChatAsync() - { - // Define the agent - ChatCompletionAgent agent = - new() - { - Instructions = "Answer questions about the menu.", - Kernel = CreateKernelWithFilter(), - Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }), - }; - - KernelPlugin plugin = KernelPluginFactory.CreateFromType<MenuPlugin>(); - agent.Kernel.Plugins.Add(plugin); - - // Create a chat for agent interaction. - AgentGroupChat chat = new(); - - // Respond to user input, invoking functions where appropriate. - await InvokeAgentAsync("Hello"); - await InvokeAgentAsync("What is the special soup?"); - await InvokeAgentAsync("What is the special drink?"); - await InvokeAgentAsync("Thank you"); - - // Display the entire chat history. - WriteChatHistory(await chat.GetChatMessagesAsync().ToArrayAsync()); - - // Local function to invoke agent and display the conversation messages. - async Task InvokeAgentAsync(string input) - { - ChatMessageContent message = new(AuthorRole.User, input); - chat.AddChatMessage(message); - this.WriteAgentChatMessage(message); - - await foreach (ChatMessageContent response in chat.InvokeAsync(agent)) - { - this.WriteAgentChatMessage(response); - } - } - } - [Fact] public async Task UseAutoFunctionInvocationFilterWithStreamingAgentInvocationAsync() { @@ -156,59 +115,6 @@ async Task InvokeAgentAsync(string input) } } - [Fact] - public async Task UseAutoFunctionInvocationFilterWithStreamingAgentChatAsync() - { - // Define the agent - ChatCompletionAgent agent = - new() - { - Instructions = "Answer questions about the menu.", - Kernel = CreateKernelWithFilter(), - Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }), - }; - - KernelPlugin plugin = KernelPluginFactory.CreateFromType<MenuPlugin>(); - agent.Kernel.Plugins.Add(plugin); - - // Create a chat for agent interaction. - AgentGroupChat chat = new(); - - // Respond to user input, invoking functions where appropriate. - await InvokeAgentAsync("Hello"); - await InvokeAgentAsync("What is the special soup?"); - await InvokeAgentAsync("What is the special drink?"); - await InvokeAgentAsync("Thank you"); - - // Display the entire chat history. - WriteChatHistory(await chat.GetChatMessagesAsync().ToArrayAsync()); - - // Local function to invoke agent and display the conversation messages. - async Task InvokeAgentAsync(string input) - { - ChatMessageContent message = new(AuthorRole.User, input); - chat.AddChatMessage(message); - this.WriteAgentChatMessage(message); - - bool isFirst = false; - await foreach (StreamingChatMessageContent response in chat.InvokeStreamingAsync(agent)) - { - if (string.IsNullOrEmpty(response.Content)) - { - continue; - } - - if (!isFirst) - { - Console.WriteLine($"\n# {response.Role} - {response.AuthorName ?? "*"}:"); - isFirst = true; - } - - Console.WriteLine($"\t > streamed: '{response.Content}'"); - } - } - } - private void WriteChatHistory(IEnumerable<ChatMessageContent> chat) { Console.WriteLine("================================"); diff --git a/dotnet/samples/Concepts/Agents/ChatCompletion_HistoryReducer.cs b/dotnet/samples/Concepts/Agents/ChatCompletion_HistoryReducer.cs index ec014236add3..6c0268c7b4ef 100644 --- a/dotnet/samples/Concepts/Agents/ChatCompletion_HistoryReducer.cs +++ b/dotnet/samples/Concepts/Agents/ChatCompletion_HistoryReducer.cs @@ -41,32 +41,6 @@ public async Task SummarizedAgentReductionAsync() await InvokeAgentAsync(agent, 50); } - /// <summary> - /// Demonstrate the use of <see cref="ChatHistoryTruncationReducer"/> when using - /// <see cref="AgentGroupChat"/> to invoke a <see cref="ChatCompletionAgent"/>. - /// </summary> - [Fact] - public async Task TruncatedChatReductionAsync() - { - // Define the agent - ChatCompletionAgent agent = CreateTruncatingAgent(10, 10); - - await InvokeChatAsync(agent, 50); - } - - /// <summary> - /// Demonstrate the use of <see cref="ChatHistorySummarizationReducer"/> when using - /// <see cref="AgentGroupChat"/> to invoke a <see cref="ChatCompletionAgent"/>. - /// </summary> - [Fact] - public async Task SummarizedChatReductionAsync() - { - // Define the agent - ChatCompletionAgent agent = CreateSummarizingAgent(10, 10); - - await InvokeChatAsync(agent, 50); - } - // Proceed with dialog by directly invoking the agent and explicitly managing the history. private async Task InvokeAgentAsync(ChatCompletionAgent agent, int messageCount) { @@ -105,48 +79,6 @@ private async Task InvokeAgentAsync(ChatCompletionAgent agent, int messageCount) } } - // Proceed with dialog with AgentGroupChat. - private async Task InvokeChatAsync(ChatCompletionAgent agent, int messageCount) - { - AgentGroupChat chat = new(); - - int lastHistoryCount = 0; - - int index = 1; - while (index <= messageCount) - { - // Provide user input - chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, $"{index}")); - Console.WriteLine($"# {AuthorRole.User}: '{index}'"); - - // Invoke and display assistant response - await foreach (ChatMessageContent message in chat.InvokeAsync(agent)) - { - Console.WriteLine($"# {message.Role} - {message.AuthorName ?? "*"}: '{message.Content}'"); - } - - index += 2; - - // Display the message count of the chat-history for visibility into reduction - // Note: Messages provided in descending order (newest first) - ChatMessageContent[] history = await chat.GetChatMessagesAsync(agent).ToArrayAsync(); - Console.WriteLine($"@ Message Count: {history.Length}\n"); - - // Display summary messages (if present) if reduction has occurred - if (history.Length < lastHistoryCount) - { - int summaryIndex = history.Length - 1; - while (history[summaryIndex].Metadata?.ContainsKey(ChatHistorySummarizationReducer.SummaryMetadataKey) ?? false) - { - Console.WriteLine($"\tSummary: {history[summaryIndex].Content}"); - --summaryIndex; - } - } - - lastHistoryCount = history.Length; - } - } - private ChatCompletionAgent CreateSummarizingAgent(int reducerMessageCount, int reducerThresholdCount) { Kernel kernel = this.CreateKernelWithChatCompletion(); diff --git a/dotnet/samples/Concepts/Agents/OpenAIAssistant_ChartMaker.cs b/dotnet/samples/Concepts/Agents/OpenAIAssistant_ChartMaker.cs index f23e7ab952b7..9ca9a8077410 100644 --- a/dotnet/samples/Concepts/Agents/OpenAIAssistant_ChartMaker.cs +++ b/dotnet/samples/Concepts/Agents/OpenAIAssistant_ChartMaker.cs @@ -27,9 +27,7 @@ await this.AssistantClient.CreateAssistantAsync( // Create the agent OpenAIAssistantAgent agent = new(assistant, this.AssistantClient); - - // Create a chat for agent interaction. - AgentGroupChat chat = new(); + AgentThread? agentThread = null; // Respond to user input try @@ -50,6 +48,11 @@ Sum 426 1622 856 2904 } finally { + if (agentThread is not null) + { + await agentThread.DeleteAsync(); + } + await this.AssistantClient.DeleteAssistantAsync(agent.Id); } @@ -57,13 +60,14 @@ Sum 426 1622 856 2904 async Task InvokeAgentAsync(string input) { ChatMessageContent message = new(AuthorRole.User, input); - chat.AddChatMessage(message); this.WriteAgentChatMessage(message); - await foreach (ChatMessageContent response in chat.InvokeAsync(agent)) + await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(message)) { this.WriteAgentChatMessage(response); await this.DownloadResponseImageAsync(response); + + agentThread = response.Thread; } } } diff --git a/dotnet/samples/Concepts/Agents/OpenAIAssistant_FileManipulation.cs b/dotnet/samples/Concepts/Agents/OpenAIAssistant_FileManipulation.cs index 915861ab2a99..0c4afbf13750 100644 --- a/dotnet/samples/Concepts/Agents/OpenAIAssistant_FileManipulation.cs +++ b/dotnet/samples/Concepts/Agents/OpenAIAssistant_FileManipulation.cs @@ -29,9 +29,7 @@ await this.AssistantClient.CreateAssistantAsync( // Create the agent OpenAIAssistantAgent agent = new(assistant, this.AssistantClient); - - // Create a chat for agent interaction. - AgentGroupChat chat = new(); + AgentThread? agentThread = null; // Respond to user input try @@ -42,6 +40,11 @@ await this.AssistantClient.CreateAssistantAsync( } finally { + if (agentThread is not null) + { + await agentThread.DeleteAsync(); + } + await this.AssistantClient.DeleteAssistantAsync(agent.Id); await this.Client.DeleteFileAsync(fileId); } @@ -50,13 +53,14 @@ await this.AssistantClient.CreateAssistantAsync( async Task InvokeAgentAsync(string input) { ChatMessageContent message = new(AuthorRole.User, input); - chat.AddChatMessage(new(AuthorRole.User, input)); this.WriteAgentChatMessage(message); - await foreach (ChatMessageContent response in chat.InvokeAsync(agent)) + await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(message)) { this.WriteAgentChatMessage(response); await this.DownloadResponseContentAsync(response); + + agentThread = response.Thread; } } } diff --git a/dotnet/samples/Concepts/Agents/OpenAIAssistant_FunctionFilters.cs b/dotnet/samples/Concepts/Agents/OpenAIAssistant_FunctionFilters.cs index a1493025b5a4..39fd09435868 100644 --- a/dotnet/samples/Concepts/Agents/OpenAIAssistant_FunctionFilters.cs +++ b/dotnet/samples/Concepts/Agents/OpenAIAssistant_FunctionFilters.cs @@ -62,46 +62,42 @@ public async Task UseAutoFunctionInvocationFilterWithStreamingAgentInvocationAsy private async Task InvokeAssistantAsync(OpenAIAssistantAgent agent) { - // Create a thread for the agent conversation. - AgentGroupChat chat = new(); + OpenAIAssistantAgentThread agentThread = new(this.AssistantClient); try { // Respond to user input, invoking functions where appropriate. ChatMessageContent message = new(AuthorRole.User, "What is the special soup?"); - chat.AddChatMessage(message); - await chat.InvokeAsync(agent).ToArrayAsync(); + await agent.InvokeAsync(message, agentThread).ToArrayAsync(); // Display the entire chat history. - ChatMessageContent[] history = await chat.GetChatMessagesAsync().Reverse().ToArrayAsync(); + ChatMessageContent[] history = await agentThread.GetMessagesAsync(MessageCollectionOrder.Ascending).ToArrayAsync(); this.WriteChatHistory(history); } finally { - await chat.ResetAsync(); + await agentThread.DeleteAsync(); await this.AssistantClient.DeleteAssistantAsync(agent.Id); } } private async Task InvokeAssistantStreamingAsync(OpenAIAssistantAgent agent) { - // Create a thread for the agent conversation. - AgentGroupChat chat = new(); + OpenAIAssistantAgentThread agentThread = new(this.AssistantClient); try { // Respond to user input, invoking functions where appropriate. ChatMessageContent message = new(AuthorRole.User, "What is the special soup?"); - chat.AddChatMessage(message); - await chat.InvokeStreamingAsync(agent).ToArrayAsync(); + await agent.InvokeStreamingAsync(message, agentThread).ToArrayAsync(); // Display the entire chat history. - ChatMessageContent[] history = await chat.GetChatMessagesAsync().Reverse().ToArrayAsync(); + ChatMessageContent[] history = await agentThread.GetMessagesAsync(MessageCollectionOrder.Ascending).ToArrayAsync(); this.WriteChatHistory(history); } finally { - await chat.ResetAsync(); + await agentThread.DeleteAsync(); await this.AssistantClient.DeleteAssistantAsync(agent.Id); } }