From 953fde69ac9b8fa2e2ce209a2e7e13cd21289444 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:39:42 +0000 Subject: [PATCH] .NET: Fix message ordering inconsistency when using AIContextProvider (#2659) * Initial plan * Fix message ordering inconsistency when using AIContextProvider Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com> * Revert to original message ordering: Input, AIContextProvider, Response Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com> * Reorder messages to ChatClient to match MessageStore order: Existing, Input, AIContextProvider Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com> * Remove redundant test methods as existing tests already verify the behavior Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com> Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com> Co-authored-by: Chris <66376200+crickman@users.noreply.github.com> --- .../ChatClient/ChatClientAgent.cs | 6 +++--- .../ChatClient/ChatClientAgentTests.cs | 20 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs index 9c5858b8e2..7d75f077ac 100644 --- a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs +++ b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs @@ -662,6 +662,9 @@ public sealed partial class ChatClientAgent : AIAgent chatMessageStoreMessages = storeMessages as IList ?? storeMessages.ToList(); } + // Add the input messages before getting context from AIContextProvider. + inputMessagesForChatClient.AddRange(inputMessages); + // If we have an AIContextProvider, we should get context from it, and update our // messages and options with the additional context. if (typedThread.AIContextProvider is not null) @@ -690,9 +693,6 @@ public sealed partial class ChatClientAgent : AIAgent chatOptions.Instructions = string.IsNullOrWhiteSpace(chatOptions.Instructions) ? aiContext.Instructions : $"{chatOptions.Instructions}\n{aiContext.Instructions}"; } } - - // Add the input messages to the end of thread messages. - inputMessagesForChatClient.AddRange(inputMessages); } // If a user provided two different thread ids, via the thread object and options, we should throw diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgentTests.cs index 5850bc56ba..29d3d3afee 100644 --- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgentTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgentTests.cs @@ -656,13 +656,13 @@ public partial class ChatClientAgentTests await agent.RunAsync(requestMessages, thread); // Assert - // Should contain: base instructions, context message, user message, base function, context function + // Should contain: base instructions, user message, context message, base function, context function Assert.Equal(2, capturedMessages.Count); Assert.Equal("base instructions\ncontext provider instructions", capturedInstructions); - Assert.Equal("context provider message", capturedMessages[0].Text); - Assert.Equal(ChatRole.System, capturedMessages[0].Role); - Assert.Equal("user message", capturedMessages[1].Text); - Assert.Equal(ChatRole.User, capturedMessages[1].Role); + Assert.Equal("user message", capturedMessages[0].Text); + Assert.Equal(ChatRole.User, capturedMessages[0].Role); + Assert.Equal("context provider message", capturedMessages[1].Text); + Assert.Equal(ChatRole.System, capturedMessages[1].Role); Assert.Equal(2, capturedTools.Count); Assert.Contains(capturedTools, t => t.Name == "base function"); Assert.Contains(capturedTools, t => t.Name == "context provider function"); @@ -2113,13 +2113,13 @@ public partial class ChatClientAgentTests _ = await updates.ToAgentRunResponseAsync(); // Assert - // Should contain: base instructions, context message, user message, base function, context function + // Should contain: base instructions, user message, context message, base function, context function Assert.Equal(2, capturedMessages.Count); Assert.Equal("base instructions\ncontext provider instructions", capturedInstructions); - Assert.Equal("context provider message", capturedMessages[0].Text); - Assert.Equal(ChatRole.System, capturedMessages[0].Role); - Assert.Equal("user message", capturedMessages[1].Text); - Assert.Equal(ChatRole.User, capturedMessages[1].Role); + Assert.Equal("user message", capturedMessages[0].Text); + Assert.Equal(ChatRole.User, capturedMessages[0].Role); + Assert.Equal("context provider message", capturedMessages[1].Text); + Assert.Equal(ChatRole.System, capturedMessages[1].Role); Assert.Equal(2, capturedTools.Count); Assert.Contains(capturedTools, t => t.Name == "base function"); Assert.Contains(capturedTools, t => t.Name == "context provider function");