@@ -347,6 +347,115 @@ public async Task ChatOptionsMergingUsesRawRepresentationFactoryWithFallbackAsyn
347347 Assert . Equal ( expectedSetting , capturedChatOptions . RawRepresentationFactory ( null ! ) ) ;
348348 }
349349
350+ /// <summary>
351+ /// Verify that <see cref="ChatOptions.Reasoning"/> from the request takes priority over the agent's.
352+ /// </summary>
353+ [ Fact ]
354+ public async Task ChatOptionsMergingUsesRequestReasoningOverAgentReasoningAsync ( )
355+ {
356+ // Arrange
357+ var agentReasoning = new ReasoningOptions { Effort = ReasoningEffort . Low , Output = ReasoningOutput . Full } ;
358+ var requestReasoning = new ReasoningOptions { Effort = ReasoningEffort . High , Output = ReasoningOutput . Full } ;
359+
360+ Mock < IChatClient > mockService = new ( ) ;
361+ ChatOptions ? capturedChatOptions = null ;
362+ mockService . Setup (
363+ s => s . GetResponseAsync (
364+ It . IsAny < IEnumerable < ChatMessage > > ( ) ,
365+ It . IsAny < ChatOptions > ( ) ,
366+ It . IsAny < CancellationToken > ( ) ) )
367+ . Callback < IEnumerable < ChatMessage > , ChatOptions , CancellationToken > ( ( msgs , opts , ct ) =>
368+ capturedChatOptions = opts )
369+ . ReturnsAsync ( new ChatResponse ( [ new ( ChatRole . Assistant , "response" ) ] ) ) ;
370+
371+ ChatClientAgent agent = new ( mockService . Object , options : new ( )
372+ {
373+ ChatOptions = new ChatOptions { Reasoning = agentReasoning }
374+ } ) ;
375+ var messages = new List < ChatMessage > { new ( ChatRole . User , "test" ) } ;
376+
377+ // Act
378+ await agent . RunAsync ( messages , options : new ChatClientAgentRunOptions ( new ChatOptions { Reasoning = requestReasoning } ) ) ;
379+
380+ // Assert
381+ Assert . NotNull ( capturedChatOptions ) ;
382+ Assert . NotNull ( capturedChatOptions . Reasoning ) ;
383+ Assert . Equal ( requestReasoning . Effort , capturedChatOptions . Reasoning . Effort ) ;
384+ Assert . Equal ( requestReasoning . Output , capturedChatOptions . Reasoning . Output ) ;
385+ }
386+
387+ /// <summary>
388+ /// Verify that <see cref="ChatOptions.Reasoning"/> falls back to the agent's when the request has none.
389+ /// </summary>
390+ [ Fact ]
391+ public async Task ChatOptionsMergingFallsBackToAgentReasoningWhenRequestHasNoneAsync ( )
392+ {
393+ // Arrange
394+ var agentReasoning = new ReasoningOptions { Effort = ReasoningEffort . Low , Output = ReasoningOutput . Full } ;
395+
396+ Mock < IChatClient > mockService = new ( ) ;
397+ ChatOptions ? capturedChatOptions = null ;
398+ mockService . Setup (
399+ s => s . GetResponseAsync (
400+ It . IsAny < IEnumerable < ChatMessage > > ( ) ,
401+ It . IsAny < ChatOptions > ( ) ,
402+ It . IsAny < CancellationToken > ( ) ) )
403+ . Callback < IEnumerable < ChatMessage > , ChatOptions , CancellationToken > ( ( msgs , opts , ct ) =>
404+ capturedChatOptions = opts )
405+ . ReturnsAsync ( new ChatResponse ( [ new ( ChatRole . Assistant , "response" ) ] ) ) ;
406+
407+ ChatClientAgent agent = new ( mockService . Object , options : new ( )
408+ {
409+ ChatOptions = new ChatOptions { Reasoning = agentReasoning }
410+ } ) ;
411+ var messages = new List < ChatMessage > { new ( ChatRole . User , "test" ) } ;
412+
413+ // Act
414+ await agent . RunAsync ( messages , options : new ChatClientAgentRunOptions ( new ChatOptions ( ) ) ) ;
415+
416+ // Assert
417+ Assert . NotNull ( capturedChatOptions ) ;
418+ Assert . NotNull ( capturedChatOptions . Reasoning ) ;
419+ Assert . Equal ( agentReasoning . Effort , capturedChatOptions . Reasoning . Effort ) ;
420+ Assert . Equal ( agentReasoning . Output , capturedChatOptions . Reasoning . Output ) ;
421+ }
422+
423+ /// <summary>
424+ /// Verify that <see cref="ChatOptions.Reasoning"/> from the request is used when the agent has none.
425+ /// </summary>
426+ [ Fact ]
427+ public async Task ChatOptionsMergingUsesRequestReasoningWhenAgentHasNoneAsync ( )
428+ {
429+ // Arrange
430+ var requestReasoning = new ReasoningOptions { Effort = ReasoningEffort . High , Output = ReasoningOutput . Full } ;
431+
432+ Mock < IChatClient > mockService = new ( ) ;
433+ ChatOptions ? capturedChatOptions = null ;
434+ mockService . Setup (
435+ s => s . GetResponseAsync (
436+ It . IsAny < IEnumerable < ChatMessage > > ( ) ,
437+ It . IsAny < ChatOptions > ( ) ,
438+ It . IsAny < CancellationToken > ( ) ) )
439+ . Callback < IEnumerable < ChatMessage > , ChatOptions , CancellationToken > ( ( msgs , opts , ct ) =>
440+ capturedChatOptions = opts )
441+ . ReturnsAsync ( new ChatResponse ( [ new ( ChatRole . Assistant , "response" ) ] ) ) ;
442+
443+ ChatClientAgent agent = new ( mockService . Object , options : new ( )
444+ {
445+ ChatOptions = new ChatOptions ( )
446+ } ) ;
447+ var messages = new List < ChatMessage > { new ( ChatRole . User , "test" ) } ;
448+
449+ // Act
450+ await agent . RunAsync ( messages , options : new ChatClientAgentRunOptions ( new ChatOptions { Reasoning = requestReasoning } ) ) ;
451+
452+ // Assert
453+ Assert . NotNull ( capturedChatOptions ) ;
454+ Assert . NotNull ( capturedChatOptions . Reasoning ) ;
455+ Assert . Equal ( requestReasoning . Effort , capturedChatOptions . Reasoning . Effort ) ;
456+ Assert . Equal ( requestReasoning . Output , capturedChatOptions . Reasoning . Output ) ;
457+ }
458+
350459 /// <summary>
351460 /// Verify that ChatOptions merging handles all scalar properties correctly.
352461 /// </summary>
0 commit comments