Skip to content

Commit cef4fa8

Browse files
Make RunAsync and RunStreamingAsync non-virtual as requested
Co-authored-by: SergeyMenshykh <[email protected]>
1 parent dc987ed commit cef4fa8

3 files changed

Lines changed: 88 additions & 66 deletions

File tree

‎dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgent.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ public Task<AgentRunResponse> RunAsync(
230230
/// The agent's response will also be added to <paramref name="thread"/> if one is provided.
231231
/// </para>
232232
/// </remarks>
233-
public virtual Task<AgentRunResponse> RunAsync(
233+
public Task<AgentRunResponse> RunAsync(
234234
IEnumerable<ChatMessage> messages,
235235
AgentThread? thread = null,
236236
AgentRunOptions? options = null,
@@ -352,7 +352,7 @@ public IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(
352352
/// to display partial results, implement progressive loading, or provide immediate feedback to users.
353353
/// </para>
354354
/// </remarks>
355-
public virtual IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(
355+
public IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(
356356
IEnumerable<ChatMessage> messages,
357357
AgentThread? thread = null,
358358
AgentRunOptions? options = null,

‎dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs‎

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Threading.Tasks;
99
using Microsoft.Extensions.AI;
1010
using Moq;
11+
using Moq.Protected;
1112

1213
namespace Microsoft.Agents.AI.Abstractions.UnitTests;
1314

@@ -33,18 +34,20 @@ public AIAgentTests()
3334

3435
this._agentMock = new Mock<AIAgent> { CallBase = true };
3536
this._agentMock
36-
.Setup(x => x.RunAsync(
37-
It.IsAny<IReadOnlyCollection<ChatMessage>>(),
38-
this._agentThreadMock.Object,
39-
It.IsAny<AgentRunOptions?>(),
40-
It.IsAny<CancellationToken>()))
37+
.Protected()
38+
.Setup<Task<AgentRunResponse>>("RunCoreAsync",
39+
ItExpr.IsAny<IEnumerable<ChatMessage>>(),
40+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
41+
ItExpr.IsAny<AgentRunOptions?>(),
42+
ItExpr.IsAny<CancellationToken>())
4143
.ReturnsAsync(this._invokeResponse);
4244
this._agentMock
43-
.Setup(x => x.RunStreamingAsync(
44-
It.IsAny<IReadOnlyCollection<ChatMessage>>(),
45-
this._agentThreadMock.Object,
46-
It.IsAny<AgentRunOptions?>(),
47-
It.IsAny<CancellationToken>()))
45+
.Protected()
46+
.Setup<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
47+
ItExpr.IsAny<IEnumerable<ChatMessage>>(),
48+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
49+
ItExpr.IsAny<AgentRunOptions?>(),
50+
ItExpr.IsAny<CancellationToken>())
4851
.Returns(ToAsyncEnumerableAsync(this._invokeStreamingResponses));
4952
}
5053

@@ -64,13 +67,14 @@ public async Task InvokeWithoutMessageCallsMockedInvokeWithEmptyArrayAsync()
6467
Assert.Equal(this._invokeResponse, response);
6568

6669
// Verify that the mocked method was called with the expected parameters
67-
this._agentMock.Verify(
68-
x => x.RunAsync(
69-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 0),
70-
this._agentThreadMock.Object,
71-
options,
72-
cancellationToken),
73-
Times.Once);
70+
this._agentMock
71+
.Protected()
72+
.Verify<Task<AgentRunResponse>>("RunCoreAsync",
73+
Times.Once(),
74+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => !messages.Any()),
75+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
76+
ItExpr.Is<AgentRunOptions?>(o => o == options),
77+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
7478
}
7579

7680
/// <summary>
@@ -90,13 +94,14 @@ public async Task InvokeWithStringMessageCallsMockedInvokeWithMessageInCollectio
9094
Assert.Equal(this._invokeResponse, response);
9195

9296
// Verify that the mocked method was called with the expected parameters
93-
this._agentMock.Verify(
94-
x => x.RunAsync(
95-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 1 && messages.First().Text == Message),
96-
this._agentThreadMock.Object,
97-
options,
98-
cancellationToken),
99-
Times.Once);
97+
this._agentMock
98+
.Protected()
99+
.Verify<Task<AgentRunResponse>>("RunCoreAsync",
100+
Times.Once(),
101+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => messages.Count() == 1 && messages.First().Text == Message),
102+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
103+
ItExpr.Is<AgentRunOptions?>(o => o == options),
104+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
100105
}
101106

102107
/// <summary>
@@ -116,13 +121,14 @@ public async Task InvokeWithSingleMessageCallsMockedInvokeWithMessageInCollectio
116121
Assert.Equal(this._invokeResponse, response);
117122

118123
// Verify that the mocked method was called with the expected parameters
119-
this._agentMock.Verify(
120-
x => x.RunAsync(
121-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 1 && messages.First() == message),
122-
this._agentThreadMock.Object,
123-
options,
124-
cancellationToken),
125-
Times.Once);
124+
this._agentMock
125+
.Protected()
126+
.Verify<Task<AgentRunResponse>>("RunCoreAsync",
127+
Times.Once(),
128+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => messages.Count() == 1 && messages.First() == message),
129+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
130+
ItExpr.Is<AgentRunOptions?>(o => o == options),
131+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
126132
}
127133

128134
/// <summary>
@@ -144,13 +150,14 @@ public async Task InvokeStreamingWithoutMessageCallsMockedInvokeWithEmptyArrayAs
144150
}
145151

146152
// Verify that the mocked method was called with the expected parameters
147-
this._agentMock.Verify(
148-
x => x.RunStreamingAsync(
149-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 0),
150-
this._agentThreadMock.Object,
151-
options,
152-
cancellationToken),
153-
Times.Once);
153+
this._agentMock
154+
.Protected()
155+
.Verify<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
156+
Times.Once(),
157+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => !messages.Any()),
158+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
159+
ItExpr.Is<AgentRunOptions?>(o => o == options),
160+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
154161
}
155162

156163
/// <summary>
@@ -173,13 +180,14 @@ public async Task InvokeStreamingWithStringMessageCallsMockedInvokeWithMessageIn
173180
}
174181

175182
// Verify that the mocked method was called with the expected parameters
176-
this._agentMock.Verify(
177-
x => x.RunStreamingAsync(
178-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 1 && messages.First().Text == Message),
179-
this._agentThreadMock.Object,
180-
options,
181-
cancellationToken),
182-
Times.Once);
183+
this._agentMock
184+
.Protected()
185+
.Verify<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
186+
Times.Once(),
187+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => messages.Count() == 1 && messages.First().Text == Message),
188+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
189+
ItExpr.Is<AgentRunOptions?>(o => o == options),
190+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
183191
}
184192

185193
/// <summary>
@@ -202,13 +210,14 @@ public async Task InvokeStreamingWithSingleMessageCallsMockedInvokeWithMessageIn
202210
}
203211

204212
// Verify that the mocked method was called with the expected parameters
205-
this._agentMock.Verify(
206-
x => x.RunStreamingAsync(
207-
It.Is<IReadOnlyCollection<ChatMessage>>(messages => messages.Count == 1 && messages.First() == message),
208-
this._agentThreadMock.Object,
209-
options,
210-
cancellationToken),
211-
Times.Once);
213+
this._agentMock
214+
.Protected()
215+
.Verify<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
216+
Times.Once(),
217+
ItExpr.Is<IEnumerable<ChatMessage>>(messages => messages.Count() == 1 && messages.First() == message),
218+
ItExpr.Is<AgentThread?>(t => t == this._agentThreadMock.Object),
219+
ItExpr.Is<AgentRunOptions?>(o => o == options),
220+
ItExpr.Is<CancellationToken>(ct => ct == cancellationToken));
212221
}
213222

214223
[Fact]

‎dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/DelegatingAIAgentTests.cs‎

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading.Tasks;
77
using Microsoft.Extensions.AI;
88
using Moq;
9+
using Moq.Protected;
910

1011
namespace Microsoft.Agents.AI.Abstractions.UnitTests;
1112

@@ -37,19 +38,21 @@ public DelegatingAIAgentTests()
3738
this._innerAgentMock.Setup(x => x.GetNewThread()).Returns(this._testThread);
3839

3940
this._innerAgentMock
40-
.Setup(x => x.RunAsync(
41-
It.IsAny<IReadOnlyCollection<ChatMessage>>(),
42-
It.IsAny<AgentThread?>(),
43-
It.IsAny<AgentRunOptions?>(),
44-
It.IsAny<CancellationToken>()))
41+
.Protected()
42+
.Setup<Task<AgentRunResponse>>("RunCoreAsync",
43+
ItExpr.IsAny<IEnumerable<ChatMessage>>(),
44+
ItExpr.IsAny<AgentThread?>(),
45+
ItExpr.IsAny<AgentRunOptions?>(),
46+
ItExpr.IsAny<CancellationToken>())
4547
.ReturnsAsync(this._testResponse);
4648

4749
this._innerAgentMock
48-
.Setup(x => x.RunStreamingAsync(
49-
It.IsAny<IReadOnlyCollection<ChatMessage>>(),
50-
It.IsAny<AgentThread?>(),
51-
It.IsAny<AgentRunOptions?>(),
52-
It.IsAny<CancellationToken>()))
50+
.Protected()
51+
.Setup<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
52+
ItExpr.IsAny<IEnumerable<ChatMessage>>(),
53+
ItExpr.IsAny<AgentThread?>(),
54+
ItExpr.IsAny<AgentRunOptions?>(),
55+
ItExpr.IsAny<CancellationToken>())
5356
.Returns(ToAsyncEnumerableAsync(this._testStreamingResponses));
5457

5558
this._delegatingAgent = new TestDelegatingAIAgent(this._innerAgentMock.Object);
@@ -158,7 +161,12 @@ public async Task RunAsyncDefaultsToInnerAgentAsync()
158161

159162
var innerAgentMock = new Mock<AIAgent>();
160163
innerAgentMock
161-
.Setup(x => x.RunAsync(expectedMessages, expectedThread, expectedOptions, expectedCancellationToken))
164+
.Protected()
165+
.Setup<Task<AgentRunResponse>>("RunCoreAsync",
166+
ItExpr.Is<IEnumerable<ChatMessage>>(m => m == expectedMessages),
167+
ItExpr.Is<AgentThread?>(t => t == expectedThread),
168+
ItExpr.Is<AgentRunOptions?>(o => o == expectedOptions),
169+
ItExpr.Is<CancellationToken>(ct => ct == expectedCancellationToken))
162170
.Returns(expectedResult.Task);
163171

164172
var delegatingAgent = new TestDelegatingAIAgent(innerAgentMock.Object);
@@ -192,7 +200,12 @@ public async Task RunStreamingAsyncDefaultsToInnerAgentAsync()
192200

193201
var innerAgentMock = new Mock<AIAgent>();
194202
innerAgentMock
195-
.Setup(x => x.RunStreamingAsync(expectedMessages, expectedThread, expectedOptions, expectedCancellationToken))
203+
.Protected()
204+
.Setup<IAsyncEnumerable<AgentRunResponseUpdate>>("RunCoreStreamingAsync",
205+
ItExpr.Is<IEnumerable<ChatMessage>>(m => m == expectedMessages),
206+
ItExpr.Is<AgentThread?>(t => t == expectedThread),
207+
ItExpr.Is<AgentRunOptions?>(o => o == expectedOptions),
208+
ItExpr.Is<CancellationToken>(ct => ct == expectedCancellationToken))
196209
.Returns(ToAsyncEnumerableAsync(expectedResults));
197210

198211
var delegatingAgent = new TestDelegatingAIAgent(innerAgentMock.Object);

0 commit comments

Comments
 (0)