From 202bfdc376d4961b3eda3211a668b7fb54475215 Mon Sep 17 00:00:00 2001
From: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
Date: Thu, 23 Oct 2025 15:37:14 +0100
Subject: [PATCH] allow a2a agent to accept non-user messages (#1661)
---
.../src/Microsoft.Agents.AI.A2A/A2AAgent.cs | 17 ++----------
.../A2AAgentTests.cs | 26 ++++++++++++-------
2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/dotnet/src/Microsoft.Agents.AI.A2A/A2AAgent.cs b/dotnet/src/Microsoft.Agents.AI.A2A/A2AAgent.cs
index 966871b534..cafbf90b87 100644
--- a/dotnet/src/Microsoft.Agents.AI.A2A/A2AAgent.cs
+++ b/dotnet/src/Microsoft.Agents.AI.A2A/A2AAgent.cs
@@ -72,7 +72,7 @@ internal sealed class A2AAgent : AIAgent
///
public override async Task RunAsync(IEnumerable messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
{
- ValidateInputMessages(messages);
+ _ = Throw.IfNull(messages);
var a2aMessage = messages.ToA2AMessage();
@@ -124,7 +124,7 @@ internal sealed class A2AAgent : AIAgent
///
public override async IAsyncEnumerable RunStreamingAsync(IEnumerable messages, AgentThread? thread = null, AgentRunOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- ValidateInputMessages(messages);
+ _ = Throw.IfNull(messages);
var a2aMessage = messages.ToA2AMessage();
@@ -177,19 +177,6 @@ internal sealed class A2AAgent : AIAgent
///
public override string? Description => this._description ?? base.Description;
- private static void ValidateInputMessages(IEnumerable messages)
- {
- _ = Throw.IfNull(messages);
-
- foreach (var message in messages)
- {
- if (message.Role != ChatRole.User)
- {
- throw new ArgumentException($"All input messages for A2A agents must have the role '{ChatRole.User}'. Found '{message.Role}'.", nameof(messages));
- }
- }
- }
-
private static void UpdateThreadConversationId(A2AAgentThread? thread, string? contextId)
{
if (thread is null)
diff --git a/dotnet/tests/Microsoft.Agents.AI.A2A.UnitTests/A2AAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.A2A.UnitTests/A2AAgentTests.cs
index 39d486f114..9399d99528 100644
--- a/dotnet/tests/Microsoft.Agents.AI.A2A.UnitTests/A2AAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.A2A.UnitTests/A2AAgentTests.cs
@@ -74,17 +74,18 @@ public sealed class A2AAgentTests : IDisposable
}
[Fact]
- public async Task RunAsync_NonUserRoleMessages_ThrowsArgumentExceptionAsync()
+ public async Task RunAsync_AllowsNonUserRoleMessagesAsync()
{
// Arrange
var inputMessages = new List
{
+ new(ChatRole.System, "I am a system message"),
new(ChatRole.Assistant, "I am an assistant message"),
new(ChatRole.User, "Valid user message")
};
// Act & Assert
- await Assert.ThrowsAsync(() => this._agent.RunAsync(inputMessages));
+ await this._agent.RunAsync(inputMessages);
}
[Fact]
@@ -345,21 +346,28 @@ public sealed class A2AAgentTests : IDisposable
}
[Fact]
- public async Task RunStreamingAsync_NonUserRoleMessages_ThrowsArgumentExceptionAsync()
+ public async Task RunStreamingAsync_AllowsNonUserRoleMessagesAsync()
{
// Arrange
+ this._handler.StreamingResponseToReturn = new AgentMessage()
+ {
+ MessageId = "stream-1",
+ Role = MessageRole.Agent,
+ Parts = [new TextPart { Text = "Response" }],
+ ContextId = "new-stream-context"
+ };
+
var inputMessages = new List
{
- new(ChatRole.Assistant, "I am an assistant message")
+ new(ChatRole.System, "I am a system message"),
+ new(ChatRole.Assistant, "I am an assistant message"),
+ new(ChatRole.User, "Valid user message")
};
// Act & Assert
- await Assert.ThrowsAsync(async () =>
+ await foreach (var _ in this._agent.RunStreamingAsync(inputMessages))
{
- await foreach (var update in this._agent.RunStreamingAsync(inputMessages))
- {
- }
- });
+ }
}
[Fact]