From ec5ea3c8a89255f761900133545bd9da88fdcb43 Mon Sep 17 00:00:00 2001 From: westey <164392973+westey-m@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:40:07 +0100 Subject: [PATCH] .NET: Remove AgentThread.GetMessagesAsync (#668) * Remove AgentThread.GetMessagesAsync * Remove unecessary using --- .../OrchestratingAgent.cs | 7 +-- .../AgentThread.cs | 18 ------- .../IChatMessageStore.cs | 4 +- .../ChatCompletion/ChatClientAgent.cs | 4 +- .../AgentThreadTests.cs | 50 ------------------- .../OpenAIChatCompletionFixture.cs | 2 +- .../OpenAIResponseFixture.cs | 2 +- 7 files changed, 8 insertions(+), 79 deletions(-) diff --git a/dotnet/src/Microsoft.Agents.Orchestration/OrchestratingAgent.cs b/dotnet/src/Microsoft.Agents.Orchestration/OrchestratingAgent.cs index dfbe7bddfe..8da88c20bc 100644 --- a/dotnet/src/Microsoft.Agents.Orchestration/OrchestratingAgent.cs +++ b/dotnet/src/Microsoft.Agents.Orchestration/OrchestratingAgent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json; using System.Threading; @@ -75,11 +76,7 @@ public abstract partial class OrchestratingAgent : AIAgent throw new InvalidOperationException("An agent service managed thread is not supported by this agent."); } - List messagesList = []; - await foreach (var threadMessage in thread.GetMessagesAsync(cancellationToken).ConfigureAwait(false)) - { - messagesList.Add(threadMessage); - } + List messagesList = (await thread.MessageStore.GetMessagesAsync(cancellationToken).ConfigureAwait(false)).ToList(); messagesList.AddRange(messages); messages = messagesList; } diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs index 63b8f07f69..afc92bc60d 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.CompilerServices; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -109,23 +108,6 @@ public class AgentThread } } - /// - /// Retrieves any messages stored in the of the thread, otherwise returns an empty collection. - /// - /// The to monitor for cancellation requests. The default is . - /// The messages from the in ascending chronological order, with the oldest message first. - public virtual async IAsyncEnumerable GetMessagesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) - { - if (this._messageStore is not null) - { - var messages = await this._messageStore!.GetMessagesAsync(cancellationToken).ConfigureAwait(false); - foreach (var message in messages) - { - yield return message; - } - } - } - /// /// Serializes the current object's state to a using the specified serialization options. /// diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/IChatMessageStore.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/IChatMessageStore.cs index d1713e9336..ad6303f36e 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/IChatMessageStore.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/IChatMessageStore.cs @@ -34,7 +34,7 @@ public interface IChatMessageStore /// since they may contain state that is specific to a thread. /// /// - Task> GetMessagesAsync(CancellationToken cancellationToken); + Task> GetMessagesAsync(CancellationToken cancellationToken = default); /// /// Adds messages to the store. @@ -42,7 +42,7 @@ public interface IChatMessageStore /// The messages to add. /// The to monitor for cancellation requests. The default is . /// An async task. - Task AddMessagesAsync(IReadOnlyCollection messages, CancellationToken cancellationToken); + Task AddMessagesAsync(IReadOnlyCollection messages, CancellationToken cancellationToken = default); /// /// Deserializes the state contained in the provided into the properties on this store. diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs index 76bb906a8d..f100fee198 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs @@ -344,9 +344,9 @@ public sealed class ChatClientAgent : AIAgent // Add any existing messages from the thread to the messages to be sent to the chat client. List threadMessages = []; - await foreach (ChatMessage message in thread.GetMessagesAsync(cancellationToken).ConfigureAwait(false)) + if (thread.MessageStore is not null) { - threadMessages.Add(message); + threadMessages.AddRange(await thread.MessageStore.GetMessagesAsync(cancellationToken).ConfigureAwait(false)); } // Add the input messages to the end of thread messages. diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs index 157fb30fdc..305fc1cd45 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs @@ -88,56 +88,6 @@ public class AgentThreadTests #endregion Constructor and Property Tests - #region GetMessagesAsync Tests - - [Fact] - public async Task GetMessagesAsyncReturnsEmptyListWhenNoStoreAsync() - { - // Arrange - var thread = new AgentThread(); - - // Act - var messages = await ToListAsync(thread.GetMessagesAsync(CancellationToken.None)); - - // Assert - Assert.Empty(messages); - } - - [Fact] - public async Task GetMessagesAsyncReturnsEmptyListWhenAgentServiceIdAsync() - { - // Arrange - var thread = new AgentThread { ConversationId = "thread-123" }; - - // Act - var messages = await ToListAsync(thread.GetMessagesAsync(CancellationToken.None)); - - // Assert - Assert.Empty(messages); - } - - [Fact] - public async Task GetMessagesAsyncReturnsMessagesFromStoreAsync() - { - // Arrange - var store = new InMemoryChatMessageStore - { - new ChatMessage(ChatRole.User, "Hello"), - new ChatMessage(ChatRole.Assistant, "Hi there!") - }; - var thread = new AgentThread { MessageStore = store }; - - // Act - var messages = await ToListAsync(thread.GetMessagesAsync(CancellationToken.None)); - - // Assert - Assert.Equal(2, messages.Count); - Assert.Equal("Hello", messages[0].Text); - Assert.Equal("Hi there!", messages[1].Text); - } - - #endregion GetMessagesAsync Tests - #region OnNewMessagesAsync Tests [Fact] diff --git a/dotnet/tests/OpenAIChatCompletion.IntegrationTests/OpenAIChatCompletionFixture.cs b/dotnet/tests/OpenAIChatCompletion.IntegrationTests/OpenAIChatCompletionFixture.cs index da5324e60e..feaacca6f8 100644 --- a/dotnet/tests/OpenAIChatCompletion.IntegrationTests/OpenAIChatCompletionFixture.cs +++ b/dotnet/tests/OpenAIChatCompletion.IntegrationTests/OpenAIChatCompletionFixture.cs @@ -32,7 +32,7 @@ public class OpenAIChatCompletionFixture : IChatClientAgentFixture public async Task> GetChatHistoryAsync(AgentThread thread) { - return await thread.GetMessagesAsync().ToListAsync(); + return thread.MessageStore is null ? [] : (await thread.MessageStore.GetMessagesAsync()).ToList(); } public Task CreateChatClientAgentAsync( diff --git a/dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponseFixture.cs b/dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponseFixture.cs index 304a955b68..1dd8a760f8 100644 --- a/dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponseFixture.cs +++ b/dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponseFixture.cs @@ -50,7 +50,7 @@ public class OpenAIResponseFixture(bool store) : IChatClientAgentFixture return [.. previousMessages, responseMessage]; } - return await thread.GetMessagesAsync().ToListAsync(); + return thread.MessageStore is null ? [] : (await thread.MessageStore.GetMessagesAsync()).ToList(); } private static ChatMessage ConvertToChatMessage(ResponseItem item)