@@ -807,15 +807,36 @@ private async Task Succeeds_Even_If_No_Handler_Assigned(ServerCapabilities serve
807807 [ Fact ]
808808 public async Task AsSamplingChatClient_NoSamplingSupport_Throws ( )
809809 {
810- await using var server = new TestServerForIChatClient ( supportsSampling : false ) ;
810+ await using var transport = new TestServerTransport ( ) ;
811+ await using var server = McpServer . Create ( transport , _options , LoggerFactory ) ;
811812
812813 Assert . Throws < InvalidOperationException > ( ( ) => server . AsSamplingChatClient ( ) ) ;
813814 }
814815
815816 [ Fact ]
816817 public async Task AsSamplingChatClient_HandlesRequestResponse ( )
817818 {
818- await using var server = new TestServerForIChatClient ( supportsSampling : true ) ;
819+ await using var transport = new TestServerTransport ( ) ;
820+ transport . MockSamplingResult = new CreateMessageResult
821+ {
822+ Content = [ new TextContentBlock { Text = "The Eiffel Tower." } ] ,
823+ Model = "amazingmodel" ,
824+ Role = Role . Assistant ,
825+ StopReason = "endTurn" ,
826+ } ;
827+ await using var server = McpServer . Create ( transport , _options , LoggerFactory ) ;
828+ var runTask = server . RunAsync ( TestContext . Current . CancellationToken ) ;
829+ await InitializeServerAsync ( transport , new ClientCapabilities { Sampling = new SamplingCapability ( ) } , TestContext . Current . CancellationToken ) ;
830+
831+ // Capture the sampling request for validation
832+ CreateMessageRequestParams ? capturedParams = null ;
833+ transport . OnMessageSent = ( message ) =>
834+ {
835+ if ( message is JsonRpcRequest request && request . Method == RequestMethods . SamplingCreateMessage )
836+ {
837+ capturedParams = JsonSerializer . Deserialize < CreateMessageRequestParams > ( request . Params , McpJsonUtilities . DefaultOptions ) ;
838+ }
839+ } ;
819840
820841 IChatClient client = server . AsSamplingChatClient ( ) ;
821842
@@ -839,6 +860,22 @@ public async Task AsSamplingChatClient_HandlesRequestResponse()
839860 Assert . Single ( response . Messages ) ;
840861 Assert . Equal ( "The Eiffel Tower." , response . Text ) ;
841862 Assert . Equal ( ChatRole . Assistant , response . Messages [ 0 ] . Role ) ;
863+
864+ // Validate the request parameters
865+ Assert . NotNull ( capturedParams ) ;
866+ Assert . Equal ( 0.75f , capturedParams . Temperature ) ;
867+ Assert . Equal ( 42 , capturedParams . MaxTokens ) ;
868+ Assert . Equal ( [ "." ] , capturedParams . StopSequences ) ;
869+ Assert . Null ( capturedParams . IncludeContext ) ;
870+ Assert . Null ( capturedParams . Metadata ) ;
871+ Assert . Null ( capturedParams . ModelPreferences ) ;
872+ Assert . Equal ( $ "You are a helpful assistant.{ Environment . NewLine } More system stuff.", capturedParams . SystemPrompt ) ;
873+ Assert . Equal ( 2 , capturedParams . Messages . Count ) ;
874+ Assert . Equal ( "I am going to France." , Assert . IsType < TextContentBlock > ( Assert . Single ( capturedParams . Messages [ 0 ] . Content ) ) . Text ) ;
875+ Assert . Equal ( "What is the most famous tower in Paris?" , Assert . IsType < TextContentBlock > ( Assert . Single ( capturedParams . Messages [ 1 ] . Content ) ) . Text ) ;
876+
877+ await transport . DisposeAsync ( ) ;
878+ await runTask ;
842879 }
843880
844881 [ Fact ]
@@ -890,62 +927,6 @@ private static async Task InitializeServerAsync(TestServerTransport transport, C
890927 await tcs . Task . WaitAsync ( TestConstants . DefaultTimeout , cancellationToken ) ;
891928 }
892929
893- private sealed class TestServerForIChatClient ( bool supportsSampling ) : McpServer
894- {
895- public override ClientCapabilities ? ClientCapabilities =>
896- supportsSampling ? new ClientCapabilities { Sampling = new SamplingCapability ( ) } :
897- null ;
898-
899- public override McpServerOptions ServerOptions => new ( ) ;
900-
901- public override Task < JsonRpcResponse > SendRequestAsync ( JsonRpcRequest request , CancellationToken cancellationToken )
902- {
903- CreateMessageRequestParams ? rp = JsonSerializer . Deserialize < CreateMessageRequestParams > ( request . Params , McpJsonUtilities . DefaultOptions ) ;
904-
905- Assert . NotNull ( rp ) ;
906- Assert . Equal ( 0.75f , rp . Temperature ) ;
907- Assert . Equal ( 42 , rp . MaxTokens ) ;
908- Assert . Equal ( [ "." ] , rp . StopSequences ) ;
909- Assert . Null ( rp . IncludeContext ) ;
910- Assert . Null ( rp . Metadata ) ;
911- Assert . Null ( rp . ModelPreferences ) ;
912-
913- Assert . Equal ( $ "You are a helpful assistant.{ Environment . NewLine } More system stuff.", rp . SystemPrompt ) ;
914-
915- Assert . Equal ( 2 , rp . Messages . Count ) ;
916- Assert . Equal ( "I am going to France." , Assert . IsType < TextContentBlock > ( Assert . Single ( rp . Messages [ 0 ] . Content ) ) . Text ) ;
917- Assert . Equal ( "What is the most famous tower in Paris?" , Assert . IsType < TextContentBlock > ( Assert . Single ( rp . Messages [ 1 ] . Content ) ) . Text ) ;
918-
919- CreateMessageResult result = new ( )
920- {
921- Content = [ new TextContentBlock { Text = "The Eiffel Tower." } ] ,
922- Model = "amazingmodel" ,
923- Role = Role . Assistant ,
924- StopReason = "endTurn" ,
925- } ;
926-
927- return Task . FromResult ( new JsonRpcResponse
928- {
929- Id = new RequestId ( "0" ) ,
930- Result = JsonSerializer . SerializeToNode ( result , McpJsonUtilities . DefaultOptions ) ,
931- } ) ;
932- }
933-
934- public override ValueTask DisposeAsync ( ) => default ;
935-
936- public override string ? SessionId => throw new NotImplementedException ( ) ;
937- public override string ? NegotiatedProtocolVersion => throw new NotImplementedException ( ) ;
938- public override Implementation ? ClientInfo => throw new NotImplementedException ( ) ;
939- public override IServiceProvider ? Services => throw new NotImplementedException ( ) ;
940- public override LoggingLevel ? LoggingLevel => throw new NotImplementedException ( ) ;
941- public override Task SendMessageAsync ( JsonRpcMessage message , CancellationToken cancellationToken = default ) =>
942- throw new NotImplementedException ( ) ;
943- public override Task RunAsync ( CancellationToken cancellationToken = default ) =>
944- throw new NotImplementedException ( ) ;
945- public override IAsyncDisposable RegisterNotificationHandler ( string method , Func < JsonRpcNotification , CancellationToken , ValueTask > handler ) =>
946- throw new NotImplementedException ( ) ;
947- }
948-
949930 [ Fact ]
950931 public async Task NotifyProgress_Should_Be_Handled ( )
951932 {
0 commit comments