11using Microsoft . Extensions . AI ;
22using Microsoft . Extensions . DependencyInjection ;
33using ModelContextProtocol . Client ;
4+ using ModelContextProtocol . Protocol . Messages ;
45using ModelContextProtocol . Protocol . Transport ;
56using ModelContextProtocol . Protocol . Types ;
67using ModelContextProtocol . Server ;
@@ -61,29 +62,39 @@ public async Task CreateSamplingHandler_ShouldHandleTextMessages(float? temperat
6162 }
6263 ] ,
6364 Temperature = temperature ,
64- MaxTokens = maxTokens
65+ MaxTokens = maxTokens ,
66+ Meta = new RequestParamsMetadata
67+ {
68+ ProgressToken = new ProgressToken ( ) ,
69+ }
6570 } ;
6671
6772 var cancellationToken = CancellationToken . None ;
68- var expectedResponse = new ChatResponse
69- {
70- Messages = { new ChatMessage { Role = ChatRole . Assistant , Contents = { new TextContent ( "Hi there!" ) } } } ,
71- ModelId = "test-model" ,
72- FinishReason = ChatFinishReason . Stop
73- } ;
73+ var expectedResponse = new [ ] {
74+ new ChatResponseUpdate
75+ {
76+ ModelId = "test-model" ,
77+ FinishReason = ChatFinishReason . Stop ,
78+ Role = ChatRole . Assistant ,
79+ Contents =
80+ [
81+ new TextContent ( "Hello, World!" ) { RawRepresentation = "Hello, World!" }
82+ ]
83+ }
84+ } . ToAsyncEnumerable ( ) ;
7485
7586 mockChatClient
76- . Setup ( client => client . GetResponseAsync ( It . IsAny < IList < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
77- . ReturnsAsync ( expectedResponse ) ;
87+ . Setup ( client => client . GetStreamingResponseAsync ( It . IsAny < IEnumerable < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
88+ . Returns ( expectedResponse ) ;
7889
7990 var handler = McpClientExtensions . CreateSamplingHandler ( mockChatClient . Object ) ;
8091
8192 // Act
82- var result = await handler ( requestParams , cancellationToken ) ;
93+ var result = await handler ( requestParams , Mock . Of < IProgress < ProgressNotificationValue > > ( ) , cancellationToken ) ;
8394
8495 // Assert
8596 Assert . NotNull ( result ) ;
86- Assert . Equal ( "Hi there !" , result . Content . Text ) ;
97+ Assert . Equal ( "Hello, World !" , result . Content . Text ) ;
8798 Assert . Equal ( "test-model" , result . Model ) ;
8899 Assert . Equal ( "assistant" , result . Role ) ;
89100 Assert . Equal ( "endTurn" , result . StopReason ) ;
@@ -96,42 +107,49 @@ public async Task CreateSamplingHandler_ShouldHandleImageMessages()
96107 var mockChatClient = new Mock < IChatClient > ( ) ;
97108 var requestParams = new CreateMessageRequestParams
98109 {
99- Messages = new [ ]
100- {
101- new SamplingMessage
102- {
103- Role = Role . User ,
104- Content = new Content
110+ Messages =
111+ [
112+ new SamplingMessage
105113 {
106- Type = "image" ,
107- MimeType = "image/png" ,
108- Data = Convert . ToBase64String ( new byte [ ] { 1 , 2 , 3 } )
114+ Role = Role . User ,
115+ Content = new Content
116+ {
117+ Type = "image" ,
118+ MimeType = "image/png" ,
119+ Data = Convert . ToBase64String ( new byte [ ] { 1 , 2 , 3 } )
120+ }
109121 }
110- }
111- } ,
122+ ] ,
112123 MaxTokens = 100
113124 } ;
114- var cancellationToken = CancellationToken . None ;
115125
116- var expectedResponse = new ChatResponse
117- {
118- Messages = { new ChatMessage { Role = ChatRole . Assistant , Contents = new [ ] { new TextContent ( "Image received!" ) } } } ,
119- ModelId = "test-model" ,
120- FinishReason = ChatFinishReason . Stop
121- } ;
126+ const string expectedData = "SGVsbG8sIFdvcmxkIQ==" ;
127+ var cancellationToken = CancellationToken . None ;
128+ var expectedResponse = new [ ] {
129+ new ChatResponseUpdate
130+ {
131+ ModelId = "test-model" ,
132+ FinishReason = ChatFinishReason . Stop ,
133+ Role = ChatRole . Assistant ,
134+ Contents =
135+ [
136+ new DataContent ( $ "data:image/png;base64,{ expectedData } ") { RawRepresentation = "Hello, World!" }
137+ ]
138+ }
139+ } . ToAsyncEnumerable ( ) ;
122140
123141 mockChatClient
124- . Setup ( client => client . GetResponseAsync ( It . IsAny < IList < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
125- . ReturnsAsync ( expectedResponse ) ;
142+ . Setup ( client => client . GetStreamingResponseAsync ( It . IsAny < IEnumerable < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
143+ . Returns ( expectedResponse ) ;
126144
127145 var handler = McpClientExtensions . CreateSamplingHandler ( mockChatClient . Object ) ;
128146
129147 // Act
130- var result = await handler ( requestParams , cancellationToken ) ;
148+ var result = await handler ( requestParams , Mock . Of < IProgress < ProgressNotificationValue > > ( ) , cancellationToken ) ;
131149
132150 // Assert
133151 Assert . NotNull ( result ) ;
134- Assert . Equal ( "Image received!" , result . Content . Text ) ;
152+ Assert . Equal ( expectedData , result . Content . Data ) ;
135153 Assert . Equal ( "test-model" , result . Model ) ;
136154 Assert . Equal ( "assistant" , result . Role ) ;
137155 Assert . Equal ( "endTurn" , result . StopReason ) ;
@@ -141,55 +159,65 @@ public async Task CreateSamplingHandler_ShouldHandleImageMessages()
141159 public async Task CreateSamplingHandler_ShouldHandleResourceMessages ( )
142160 {
143161 // Arrange
162+ const string data = "SGVsbG8sIFdvcmxkIQ==" ;
163+ string content = $ "data:application/octet-stream;base64,{ data } ";
144164 var mockChatClient = new Mock < IChatClient > ( ) ;
165+ var resource = new BlobResourceContents
166+ {
167+ Blob = data ,
168+ MimeType = "application/octet-stream" ,
169+ Uri = "data:application/octet-stream"
170+ } ;
171+
145172 var requestParams = new CreateMessageRequestParams
146173 {
147- Messages = new [ ]
148- {
149- new SamplingMessage
150- {
151- Role = Role . User ,
152- Content = new Content
174+ Messages =
175+ [
176+ new SamplingMessage
153177 {
154- Type = "resource" ,
155- Resource = new ResourceContents
178+ Role = Role . User ,
179+ Content = new Content
156180 {
157- Text = "Resource text" ,
158- Blob = Convert . ToBase64String ( new byte [ ] { 4 , 5 , 6 } ) ,
159- MimeType = "application/octet-stream"
160- }
181+ Type = "resource" ,
182+ Resource = resource
183+ } ,
161184 }
162- }
163- } ,
185+ ] ,
164186 MaxTokens = 100
165187 } ;
166- var cancellationToken = CancellationToken . None ;
167188
168- var expectedResponse = new ChatResponse
169- {
170- Messages = { new ChatMessage { Role = ChatRole . Assistant , Contents = new [ ] { new TextContent ( "Resource processed!" ) } } } ,
171- ModelId = "test-model" ,
172- FinishReason = ChatFinishReason . Stop
173- } ;
189+ var cancellationToken = CancellationToken . None ;
190+ var expectedResponse = new [ ] {
191+ new ChatResponseUpdate
192+ {
193+ ModelId = "test-model" ,
194+ FinishReason = ChatFinishReason . Stop ,
195+ AuthorName = "bot" ,
196+ Role = ChatRole . Assistant ,
197+ Contents =
198+ [
199+ resource . ToAIContent ( )
200+ ]
201+ }
202+ } . ToAsyncEnumerable ( ) ;
174203
175204 mockChatClient
176- . Setup ( client => client . GetResponseAsync ( It . IsAny < IList < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
177- . ReturnsAsync ( expectedResponse ) ;
205+ . Setup ( client => client . GetStreamingResponseAsync ( It . IsAny < IEnumerable < ChatMessage > > ( ) , It . IsAny < ChatOptions > ( ) , cancellationToken ) )
206+ . Returns ( expectedResponse ) ;
178207
179208 var handler = McpClientExtensions . CreateSamplingHandler ( mockChatClient . Object ) ;
180209
181210 // Act
182- var result = await handler ( requestParams , cancellationToken ) ;
211+ var result = await handler ( requestParams , Mock . Of < IProgress < ProgressNotificationValue > > ( ) , cancellationToken ) ;
183212
184213 // Assert
185214 Assert . NotNull ( result ) ;
186- Assert . Equal ( "Resource processed!" , result . Content . Text ) ;
187215 Assert . Equal ( "test-model" , result . Model ) ;
188- Assert . Equal ( "assistant" , result . Role ) ;
216+ Assert . Equal ( ChatRole . Assistant . ToString ( ) , result . Role ) ;
189217 Assert . Equal ( "endTurn" , result . StopReason ) ;
190218 }
191219
192- public ValueTask DisposeAsync ( )
220+ public async ValueTask DisposeAsync ( )
193221 {
194222 await _cts . CancelAsync ( ) ;
195223
0 commit comments