diff --git a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
index 44a136da3e..e59ec698b8 100644
--- a/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
+++ b/dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
@@ -549,6 +549,7 @@ internal async Task NotifyProvidersOfFailureAsync(
requestChatOptions.ModelId ??= this._agentOptions.ChatOptions.ModelId;
requestChatOptions.PresencePenalty ??= this._agentOptions.ChatOptions.PresencePenalty;
requestChatOptions.ResponseFormat ??= this._agentOptions.ChatOptions.ResponseFormat;
+ requestChatOptions.Reasoning ??= this._agentOptions.ChatOptions.Reasoning;
requestChatOptions.Seed ??= this._agentOptions.ChatOptions.Seed;
requestChatOptions.Temperature ??= this._agentOptions.ChatOptions.Temperature;
requestChatOptions.TopP ??= this._agentOptions.ChatOptions.TopP;
diff --git a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgent_ChatOptionsMergingTests.cs b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgent_ChatOptionsMergingTests.cs
index e4df863ce0..c4766b83f0 100644
--- a/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgent_ChatOptionsMergingTests.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgent_ChatOptionsMergingTests.cs
@@ -347,6 +347,115 @@ public async Task ChatOptionsMergingUsesRawRepresentationFactoryWithFallbackAsyn
Assert.Equal(expectedSetting, capturedChatOptions.RawRepresentationFactory(null!));
}
+ ///
+ /// Verify that from the request takes priority over the agent's.
+ ///
+ [Fact]
+ public async Task ChatOptionsMergingUsesRequestReasoningOverAgentReasoningAsync()
+ {
+ // Arrange
+ var agentReasoning = new ReasoningOptions { Effort = ReasoningEffort.Low, Output = ReasoningOutput.Full };
+ var requestReasoning = new ReasoningOptions { Effort = ReasoningEffort.High, Output = ReasoningOutput.Full };
+
+ Mock mockService = new();
+ ChatOptions? capturedChatOptions = null;
+ mockService.Setup(
+ s => s.GetResponseAsync(
+ It.IsAny>(),
+ It.IsAny(),
+ It.IsAny()))
+ .Callback, ChatOptions, CancellationToken>((msgs, opts, ct) =>
+ capturedChatOptions = opts)
+ .ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
+
+ ChatClientAgent agent = new(mockService.Object, options: new()
+ {
+ ChatOptions = new ChatOptions { Reasoning = agentReasoning }
+ });
+ var messages = new List { new(ChatRole.User, "test") };
+
+ // Act
+ await agent.RunAsync(messages, options: new ChatClientAgentRunOptions(new ChatOptions { Reasoning = requestReasoning }));
+
+ // Assert
+ Assert.NotNull(capturedChatOptions);
+ Assert.NotNull(capturedChatOptions.Reasoning);
+ Assert.Equal(requestReasoning.Effort, capturedChatOptions.Reasoning.Effort);
+ Assert.Equal(requestReasoning.Output, capturedChatOptions.Reasoning.Output);
+ }
+
+ ///
+ /// Verify that falls back to the agent's when the request has none.
+ ///
+ [Fact]
+ public async Task ChatOptionsMergingFallsBackToAgentReasoningWhenRequestHasNoneAsync()
+ {
+ // Arrange
+ var agentReasoning = new ReasoningOptions { Effort = ReasoningEffort.Low, Output = ReasoningOutput.Full };
+
+ Mock mockService = new();
+ ChatOptions? capturedChatOptions = null;
+ mockService.Setup(
+ s => s.GetResponseAsync(
+ It.IsAny>(),
+ It.IsAny(),
+ It.IsAny()))
+ .Callback, ChatOptions, CancellationToken>((msgs, opts, ct) =>
+ capturedChatOptions = opts)
+ .ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
+
+ ChatClientAgent agent = new(mockService.Object, options: new()
+ {
+ ChatOptions = new ChatOptions { Reasoning = agentReasoning }
+ });
+ var messages = new List { new(ChatRole.User, "test") };
+
+ // Act
+ await agent.RunAsync(messages, options: new ChatClientAgentRunOptions(new ChatOptions()));
+
+ // Assert
+ Assert.NotNull(capturedChatOptions);
+ Assert.NotNull(capturedChatOptions.Reasoning);
+ Assert.Equal(agentReasoning.Effort, capturedChatOptions.Reasoning.Effort);
+ Assert.Equal(agentReasoning.Output, capturedChatOptions.Reasoning.Output);
+ }
+
+ ///
+ /// Verify that from the request is used when the agent has none.
+ ///
+ [Fact]
+ public async Task ChatOptionsMergingUsesRequestReasoningWhenAgentHasNoneAsync()
+ {
+ // Arrange
+ var requestReasoning = new ReasoningOptions { Effort = ReasoningEffort.High, Output = ReasoningOutput.Full };
+
+ Mock mockService = new();
+ ChatOptions? capturedChatOptions = null;
+ mockService.Setup(
+ s => s.GetResponseAsync(
+ It.IsAny>(),
+ It.IsAny(),
+ It.IsAny()))
+ .Callback, ChatOptions, CancellationToken>((msgs, opts, ct) =>
+ capturedChatOptions = opts)
+ .ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
+
+ ChatClientAgent agent = new(mockService.Object, options: new()
+ {
+ ChatOptions = new ChatOptions()
+ });
+ var messages = new List { new(ChatRole.User, "test") };
+
+ // Act
+ await agent.RunAsync(messages, options: new ChatClientAgentRunOptions(new ChatOptions { Reasoning = requestReasoning }));
+
+ // Assert
+ Assert.NotNull(capturedChatOptions);
+ Assert.NotNull(capturedChatOptions.Reasoning);
+ Assert.Equal(requestReasoning.Effort, capturedChatOptions.Reasoning.Effort);
+ Assert.Equal(requestReasoning.Output, capturedChatOptions.Reasoning.Output);
+ }
+
///
/// Verify that ChatOptions merging handles all scalar properties correctly.
///