@@ -263,6 +263,68 @@ describe('InferenceGatewayClient', () => {
263
263
) ;
264
264
} ) ;
265
265
266
+ it ( 'should handle streaming chat completions reasoning and content' , async ( ) => {
267
+ const mockRequest = {
268
+ model : 'gpt-4o' ,
269
+ messages : [
270
+ { role : MessageRole . user , content : 'Hello' } ,
271
+ ] ,
272
+ stream : true ,
273
+ } ;
274
+ const mockStream = new TransformStream ( ) ;
275
+ const writer = mockStream . writable . getWriter ( ) ;
276
+ const encoder = new TextEncoder ( ) ;
277
+ mockFetch . mockResolvedValueOnce ( {
278
+ ok : true ,
279
+ body : mockStream . readable ,
280
+ } ) ;
281
+ const callbacks = {
282
+ onOpen : jest . fn ( ) ,
283
+ onChunk : jest . fn ( ) ,
284
+ onReasoning : jest . fn ( ) ,
285
+ onContent : jest . fn ( ) ,
286
+ onFinish : jest . fn ( ) ,
287
+ } ;
288
+ const streamPromise = client . streamChatCompletion ( mockRequest , callbacks ) ;
289
+ await writer . write (
290
+ encoder . encode (
291
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}\n\n' +
292
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"","reasoning_content":"This"},"finish_reason":null}]}\n\n' +
293
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"","reasoning_content":" is"},"finish_reason":null}]}\n\n' +
294
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"","reasoning_content":" a"},"finish_reason":"stop"}]}\n\n' +
295
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"","reasoning_content":" reasoning"},"finish_reason":"stop"}]}\n\n' +
296
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"","reasoning_content":" content"},"finish_reason":"stop"}]}\n\n' +
297
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}\n\n' +
298
+ 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677652288,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}\n\n' +
299
+ 'data: [DONE]\n\n'
300
+ )
301
+ ) ;
302
+ await writer . close ( ) ;
303
+ await streamPromise ;
304
+ expect ( callbacks . onOpen ) . toHaveBeenCalledTimes ( 1 ) ;
305
+ expect ( callbacks . onChunk ) . toHaveBeenCalledTimes ( 8 ) ;
306
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledTimes ( 5 ) ;
307
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledWith ( 'This' ) ;
308
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledWith ( ' is' ) ;
309
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledWith ( ' a' ) ;
310
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledWith ( ' reasoning' ) ;
311
+ expect ( callbacks . onReasoning ) . toHaveBeenCalledWith ( ' content' ) ;
312
+ expect ( callbacks . onContent ) . toHaveBeenCalledTimes ( 2 ) ;
313
+ expect ( callbacks . onContent ) . toHaveBeenCalledWith ( 'Hello' ) ;
314
+ expect ( callbacks . onContent ) . toHaveBeenCalledWith ( '!' ) ;
315
+ expect ( callbacks . onFinish ) . toHaveBeenCalledTimes ( 1 ) ;
316
+ expect ( mockFetch ) . toHaveBeenCalledWith (
317
+ 'http://localhost:8080/v1/chat/completions' ,
318
+ expect . objectContaining ( {
319
+ method : 'POST' ,
320
+ body : JSON . stringify ( {
321
+ ...mockRequest ,
322
+ stream : true ,
323
+ } ) ,
324
+ } )
325
+ ) ;
326
+ } ) ;
327
+
266
328
it ( 'should handle tool calls in streaming chat completions' , async ( ) => {
267
329
const mockRequest = {
268
330
model : 'gpt-4o' ,
0 commit comments