diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props
index d0fab6bf1dc..d6b664ceb85 100644
--- a/dotnet/Directory.Packages.props
+++ b/dotnet/Directory.Packages.props
@@ -159,7 +159,7 @@
-
+
all
@@ -170,27 +170,27 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj b/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
index ccb41befe91..5376b3c7cdc 100644
--- a/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
+++ b/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj
@@ -53,7 +53,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -61,15 +61,15 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/dotnet/samples/02-agents/AgentWithRAG/AgentWithRAG_Step05_Neo4jGraphRAG/AgentWithRAG_Step05_Neo4jGraphRAG.csproj b/dotnet/samples/02-agents/AgentWithRAG/AgentWithRAG_Step05_Neo4jGraphRAG/AgentWithRAG_Step05_Neo4jGraphRAG.csproj
index a9d07b246e3..dd07c33f219 100644
--- a/dotnet/samples/02-agents/AgentWithRAG/AgentWithRAG_Step05_Neo4jGraphRAG/AgentWithRAG_Step05_Neo4jGraphRAG.csproj
+++ b/dotnet/samples/02-agents/AgentWithRAG/AgentWithRAG_Step05_Neo4jGraphRAG/AgentWithRAG_Step05_Neo4jGraphRAG.csproj
@@ -27,7 +27,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -35,15 +35,15 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs
index 2ba6472244e..91af566e0f0 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs
@@ -458,13 +458,15 @@ public async Task RunAsync_NestedRun_RestoresOuterCurrentRunContextAsync()
ItExpr.IsAny(),
ItExpr.IsAny(),
ItExpr.IsAny())
- .Returns(async () =>
- {
- outerContextBeforeInnerRun = AIAgent.CurrentRunContext;
- await innerAgentMock.Object.RunAsync("Inner request", innerSession);
- outerContextAfterInnerRun = AIAgent.CurrentRunContext;
- return new AgentResponse(new ChatMessage(ChatRole.Assistant, "Outer response"));
- });
+ .Returns(RunCoreAsync);
+
+ async Task RunCoreAsync()
+ {
+ outerContextBeforeInnerRun = AIAgent.CurrentRunContext;
+ await innerAgentMock.Object.RunAsync("Inner request", innerSession);
+ outerContextAfterInnerRun = AIAgent.CurrentRunContext;
+ return new AgentResponse(new ChatMessage(ChatRole.Assistant, "Outer response"));
+ }
// Act
await outerAgentMock.Object.RunAsync("Outer request", outerSession);
diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/MessageInjectingChatClientTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/MessageInjectingChatClientTests.cs
index ce6f20681b8..3292f804773 100644
--- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/MessageInjectingChatClientTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/MessageInjectingChatClientTests.cs
@@ -10,6 +10,8 @@
using Moq;
using Moq.Protected;
+#pragma warning disable Moq1206
+
namespace Microsoft.Agents.AI.UnitTests;
///
@@ -176,18 +178,20 @@ public async Task RunAsync_LoopsInternally_WhenNoActionableFCCButPendingMessages
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount == 1)
{
- serviceCallCount++;
- if (serviceCallCount == 1)
- {
- // First call — simulate that something enqueues a message (e.g., a provider or background task)
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected during first call")], ct);
- }
+ // First call — simulate that something enqueues a message (e.g., a provider or background task)
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected during first call")], ct);
+ }
- // Return a plain text response (no FunctionCallContent) to trigger the internal loop
- return new ChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")]);
- });
+ // Return a plain text response (no FunctionCallContent) to trigger the internal loop
+ return new ChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")]);
+ }
Mock mockChatHistoryProvider = new(null, null, null);
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
@@ -237,21 +241,23 @@ public async Task RunAsync_DoesNotLoopInternally_WhenActionableFCCPresentAsync()
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
- {
- serviceCallCount++;
- if (serviceCallCount == 1)
- {
- // Enqueue a message during the first call
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
- // Return a response with an actionable FunctionCallContent
- return new ChatResponse([new(ChatRole.Assistant,
- [new FunctionCallContent("call1", "myTool", new Dictionary())])]);
- }
+ .Returns(GetResponseAsync);
- // Subsequent calls return plain text (the FCC loop will call back after tool execution)
- return new ChatResponse([new(ChatRole.Assistant, "final")]);
- });
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount == 1)
+ {
+ // Enqueue a message during the first call
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
+ // Return a response with an actionable FunctionCallContent
+ return new ChatResponse([new(ChatRole.Assistant,
+ [new FunctionCallContent("call1", "myTool", new Dictionary())])]);
+ }
+
+ // Subsequent calls return plain text (the FCC loop will call back after tool execution)
+ return new ChatResponse([new(ChatRole.Assistant, "final")]);
+ }
Mock mockChatHistoryProvider = new(null, null, null);
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
@@ -307,26 +313,28 @@ public async Task RunAsync_ActionableFCCOnLaterIteration_AggregatesUsageAcrossIn
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount == 1)
{
- serviceCallCount++;
- if (serviceCallCount == 1)
- {
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
- return new ChatResponse([new(ChatRole.Assistant, "queued")]) { Usage = CreateUsageForCall(serviceCallCount) };
- }
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
+ return new ChatResponse([new(ChatRole.Assistant, "queued")]) { Usage = CreateUsageForCall(serviceCallCount) };
+ }
- if (serviceCallCount == 2)
+ if (serviceCallCount == 2)
+ {
+ return new ChatResponse([new(ChatRole.Assistant,
+ [new FunctionCallContent("call1", "myTool", new Dictionary())])])
{
- return new ChatResponse([new(ChatRole.Assistant,
- [new FunctionCallContent("call1", "myTool", new Dictionary())])])
- {
- Usage = CreateUsageForCall(serviceCallCount)
- };
- }
+ Usage = CreateUsageForCall(serviceCallCount)
+ };
+ }
- return new ChatResponse([new(ChatRole.Assistant, "final")]) { Usage = CreateUsageForCall(serviceCallCount) };
- });
+ return new ChatResponse([new(ChatRole.Assistant, "final")]) { Usage = CreateUsageForCall(serviceCallCount) };
+ }
var tool = AIFunctionFactory.Create(() => "tool result", "myTool", "A test tool");
ChatClientAgent agent = new(mockService.Object, options: new()
@@ -370,20 +378,22 @@ public async Task RunAsync_LoopsInternally_WhenOnlyInformationalOnlyFCCAndPendin
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
- {
- serviceCallCount++;
- if (serviceCallCount == 1)
- {
- // Enqueue a message during the first call
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
- // Return a response with InformationalOnly FCC (not actionable)
- return new ChatResponse([new(ChatRole.Assistant,
- [new FunctionCallContent("call1", "myTool", new Dictionary()) { InformationalOnly = true }])]);
- }
+ .Returns(GetResponseAsync);
- return new ChatResponse([new(ChatRole.Assistant, "final")]);
- });
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount == 1)
+ {
+ // Enqueue a message during the first call
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
+ // Return a response with InformationalOnly FCC (not actionable)
+ return new ChatResponse([new(ChatRole.Assistant,
+ [new FunctionCallContent("call1", "myTool", new Dictionary()) { InformationalOnly = true }])]);
+ }
+
+ return new ChatResponse([new(ChatRole.Assistant, "final")]);
+ }
Mock mockChatHistoryProvider = new(null, null, null);
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
@@ -434,24 +444,26 @@ public async Task RunAsync_PropagatesConversationId_AcrossInternalLoopIterations
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable _, ChatOptions? opts, CancellationToken ct) =>
- {
- serviceCallCount++;
- capturedConversationIds.Add(opts?.ConversationId);
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable _, ChatOptions? opts, CancellationToken ct)
+ {
+ serviceCallCount++;
+ capturedConversationIds.Add(opts?.ConversationId);
- if (serviceCallCount == 1)
+ if (serviceCallCount == 1)
+ {
+ // First call: inject a message and return a ConversationId
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
+ return new ChatResponse([new(ChatRole.Assistant, "first response")])
{
- // First call: inject a message and return a ConversationId
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected")], ct);
- return new ChatResponse([new(ChatRole.Assistant, "first response")])
- {
- ConversationId = "conv-123",
- };
- }
+ ConversationId = "conv-123",
+ };
+ }
- // Second call (from loop): should have the propagated ConversationId
- return new ChatResponse([new(ChatRole.Assistant, "second response")]);
- });
+ // Second call (from loop): should have the propagated ConversationId
+ return new ChatResponse([new(ChatRole.Assistant, "second response")]);
+ }
ChatClientAgent agent = new(mockService.Object, options: new()
{
@@ -491,25 +503,27 @@ public async Task RunAsync_DeliversInjectedMessages_AfterSessionSerializationRou
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ if (runCount == 1)
{
- if (runCount == 1)
- {
- capturedMessagesFirstRun.AddRange(msgs);
+ capturedMessagesFirstRun.AddRange(msgs);
- // Inject a message during the first run — this will remain pending (not drained)
- // because we return an actionable FCC that causes the parent loop to take over.
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected before serialization")], ct);
+ // Inject a message during the first run — this will remain pending (not drained)
+ // because we return an actionable FCC that causes the parent loop to take over.
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, "injected before serialization")], ct);
- // Return actionable FCC so the injection loop does NOT drain the message
- return new ChatResponse([new(ChatRole.Assistant,
- [new FunctionCallContent("call1", "myTool", new Dictionary())])]);
- }
+ // Return actionable FCC so the injection loop does NOT drain the message
+ return new ChatResponse([new(ChatRole.Assistant,
+ [new FunctionCallContent("call1", "myTool", new Dictionary())])]);
+ }
- // Second run (after deserialization) — capture what messages come through
- capturedMessagesSecondRun.AddRange(msgs);
- return new ChatResponse([new(ChatRole.Assistant, "final response")]);
- });
+ // Second run (after deserialization) — capture what messages come through
+ capturedMessagesSecondRun.AddRange(msgs);
+ return new ChatResponse([new(ChatRole.Assistant, "final response")]);
+ }
Mock mockChatHistoryProvider = new(null, null, null);
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
@@ -620,20 +634,22 @@ public async Task RunAsync_LoopsInternally_AggregatesUsageAcrossIterationsAsync(
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount < 3)
{
- serviceCallCount++;
- if (serviceCallCount < 3)
- {
- // Enqueue a message so the injection loop runs again.
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, $"injected {serviceCallCount}")], ct);
- }
+ // Enqueue a message so the injection loop runs again.
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, $"injected {serviceCallCount}")], ct);
+ }
- return new ChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")])
- {
- Usage = CreateUsageForCall(serviceCallCount),
- };
- });
+ return new ChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")])
+ {
+ Usage = CreateUsageForCall(serviceCallCount),
+ };
+ }
ChatClientAgent agent = new(mockService.Object, options: new()
{
@@ -674,21 +690,23 @@ public async Task RunAsync_InnerClientReturnsDerivedResponse_PreservesRuntimeTyp
It.IsAny>(),
It.IsAny(),
It.IsAny()))
- .Returns(async (IEnumerable msgs, ChatOptions? _, CancellationToken ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable msgs, ChatOptions? _, CancellationToken ct)
+ {
+ serviceCallCount++;
+ if (serviceCallCount < 3)
{
- serviceCallCount++;
- if (serviceCallCount < 3)
- {
- // Enqueue a message so the injection loop runs again.
- await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, $"injected {serviceCallCount}")], ct);
- }
+ // Enqueue a message so the injection loop runs again.
+ await injectorRef!.EnqueueMessagesAsync(sessionRef!, [new ChatMessage(ChatRole.User, $"injected {serviceCallCount}")], ct);
+ }
- return new TestDerivedChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")])
- {
- DerivedState = $"call {serviceCallCount}",
- Usage = new UsageDetails { InputTokenCount = serviceCallCount, OutputTokenCount = serviceCallCount * 10 },
- };
- });
+ return new TestDerivedChatResponse([new(ChatRole.Assistant, $"response {serviceCallCount}")])
+ {
+ DerivedState = $"call {serviceCallCount}",
+ Usage = new UsageDetails { InputTokenCount = serviceCallCount, OutputTokenCount = serviceCallCount * 10 },
+ };
+ }
ChatClientAgent agent = new(mockService.Object, options: new()
{
diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/FunctionInvocationDelegatingAgentTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/FunctionInvocationDelegatingAgentTests.cs
index 68228155a77..d39edde983d 100644
--- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/FunctionInvocationDelegatingAgentTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/FunctionInvocationDelegatingAgentTests.cs
@@ -8,6 +8,8 @@
using Microsoft.Extensions.AI;
using Moq;
+#pragma warning disable Moq1206
+
namespace Microsoft.Agents.AI.UnitTests;
///
@@ -467,16 +469,19 @@ public async Task RunAsync_DirectFunctionInvocation_MiddlewareHandlesNullCurrent
// Setup mock to directly invoke the function (bypassing FunctionInvokingChatClient)
mockChatClient.Setup(c => c.GetResponseAsync(It.IsAny>(), It.IsAny(), It.IsAny()))
- .Returns, ChatOptions, CancellationToken>(async (messages, options, ct) =>
+ .Returns(GetResponseAsync);
+
+ async Task GetResponseAsync(IEnumerable messages, ChatOptions? options, CancellationToken ct)
+ {
+ // Directly invoke the function to simulate null CurrentContext scenario
+ if (options?.Tools?.FirstOrDefault() is AIFunction function)
{
- // Directly invoke the function to simulate null CurrentContext scenario
- if (options?.Tools?.FirstOrDefault() is AIFunction function)
- {
- executionOrder.Add("Direct-Function-Invocation");
- await function.InvokeAsync([], ct);
- }
- return new ChatResponse([new ChatMessage(ChatRole.Assistant, "Response after direct invocation")]);
- });
+ executionOrder.Add("Direct-Function-Invocation");
+ await function.InvokeAsync([], ct);
+ }
+
+ return new ChatResponse([new ChatMessage(ChatRole.Assistant, "Response after direct invocation")]);
+ }
var innerAgent = new ChatClientAgent(mockChatClient.Object, new ChatClientAgentOptions
{
diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/BackgroundAgents/BackgroundAgentsProviderTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/BackgroundAgents/BackgroundAgentsProviderTests.cs
index 4ead3bfb1cc..ceb07610908 100644
--- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/BackgroundAgents/BackgroundAgentsProviderTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/Harness/BackgroundAgents/BackgroundAgentsProviderTests.cs
@@ -10,6 +10,8 @@
using Moq;
using Moq.Protected;
+#pragma warning disable Moq1206
+
namespace Microsoft.Agents.AI.UnitTests;
///
@@ -1743,11 +1745,7 @@ private static AIAgent CreateMockAgentWithGatedSession(string name, Task session
.Setup>(
"CreateSessionCoreAsync",
ItExpr.IsAny())
- .Returns(async () =>
- {
- await sessionGate;
- return new ChatClientAgentSession();
- });
+ .Returns(CreateSessionCoreAsync);
mock.Protected()
.Setup>(
"RunCoreAsync",
@@ -1757,6 +1755,12 @@ private static AIAgent CreateMockAgentWithGatedSession(string name, Task session
ItExpr.IsAny())
.Returns(callback);
return mock.Object;
+
+ async ValueTask CreateSessionCoreAsync()
+ {
+ await sessionGate;
+ return new ChatClientAgentSession();
+ }
}
private static async Task<(IEnumerable Tools, BackgroundAgentsProvider Provider, AgentSession Session)> CreateToolsWithSessionAsync(AIAgent agent)