@@ -358,6 +358,271 @@ func TestCreateChatCompletionStreamRateLimitError(t *testing.T) {
358358	t .Logf ("%+v\n " , apiErr )
359359}
360360
361+ func  TestCreateChatCompletionStreamWithRefusal (t  * testing.T ) {
362+ 	client , server , teardown  :=  setupOpenAITestServer ()
363+ 	defer  teardown ()
364+ 	server .RegisterHandler ("/v1/chat/completions" , func (w  http.ResponseWriter , _  * http.Request ) {
365+ 		w .Header ().Set ("Content-Type" , "text/event-stream" )
366+ 
367+ 		dataBytes  :=  []byte {}
368+ 
369+ 		//nolint:lll 
370+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"1","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"finish_reason":null}]}` )... )
371+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
372+ 
373+ 		//nolint:lll 
374+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"2","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"refusal":"Hello"},"finish_reason":null}]}` )... )
375+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
376+ 
377+ 		//nolint:lll 
378+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"3","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"refusal":" World"},"finish_reason":null}]}` )... )
379+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
380+ 
381+ 		//nolint:lll 
382+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"4","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}` )... )
383+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
384+ 
385+ 		dataBytes  =  append (dataBytes , []byte ("data: [DONE]\n \n " )... )
386+ 
387+ 		_ , err  :=  w .Write (dataBytes )
388+ 		checks .NoError (t , err , "Write error" )
389+ 	})
390+ 
391+ 	stream , err  :=  client .CreateChatCompletionStream (context .Background (), openai.ChatCompletionRequest {
392+ 		MaxTokens : 2000 ,
393+ 		Model :     openai .GPT4oMini20240718 ,
394+ 		Messages : []openai.ChatCompletionMessage {
395+ 			{
396+ 				Role :    openai .ChatMessageRoleUser ,
397+ 				Content : "Hello!" ,
398+ 			},
399+ 		},
400+ 		Stream : true ,
401+ 	})
402+ 	checks .NoError (t , err , "CreateCompletionStream returned error" )
403+ 	defer  stream .Close ()
404+ 
405+ 	expectedResponses  :=  []openai.ChatCompletionStreamResponse {
406+ 		{
407+ 			ID :                "1" ,
408+ 			Object :            "chat.completion.chunk" ,
409+ 			Created :           1729585728 ,
410+ 			Model :             openai .GPT4oMini20240718 ,
411+ 			SystemFingerprint : "fp_d9767fc5b9" ,
412+ 			Choices : []openai.ChatCompletionStreamChoice {
413+ 				{
414+ 					Index : 0 ,
415+ 					Delta : openai.ChatCompletionStreamChoiceDelta {},
416+ 				},
417+ 			},
418+ 		},
419+ 		{
420+ 			ID :                "2" ,
421+ 			Object :            "chat.completion.chunk" ,
422+ 			Created :           1729585728 ,
423+ 			Model :             openai .GPT4oMini20240718 ,
424+ 			SystemFingerprint : "fp_d9767fc5b9" ,
425+ 			Choices : []openai.ChatCompletionStreamChoice {
426+ 				{
427+ 					Index : 0 ,
428+ 					Delta : openai.ChatCompletionStreamChoiceDelta {
429+ 						Refusal : "Hello" ,
430+ 					},
431+ 				},
432+ 			},
433+ 		},
434+ 		{
435+ 			ID :                "3" ,
436+ 			Object :            "chat.completion.chunk" ,
437+ 			Created :           1729585728 ,
438+ 			Model :             openai .GPT4oMini20240718 ,
439+ 			SystemFingerprint : "fp_d9767fc5b9" ,
440+ 			Choices : []openai.ChatCompletionStreamChoice {
441+ 				{
442+ 					Index : 0 ,
443+ 					Delta : openai.ChatCompletionStreamChoiceDelta {
444+ 						Refusal : " World" ,
445+ 					},
446+ 				},
447+ 			},
448+ 		},
449+ 		{
450+ 			ID :                "4" ,
451+ 			Object :            "chat.completion.chunk" ,
452+ 			Created :           1729585728 ,
453+ 			Model :             openai .GPT4oMini20240718 ,
454+ 			SystemFingerprint : "fp_d9767fc5b9" ,
455+ 			Choices : []openai.ChatCompletionStreamChoice {
456+ 				{
457+ 					Index :        0 ,
458+ 					FinishReason : "stop" ,
459+ 				},
460+ 			},
461+ 		},
462+ 	}
463+ 
464+ 	for  ix , expectedResponse  :=  range  expectedResponses  {
465+ 		b , _  :=  json .Marshal (expectedResponse )
466+ 		t .Logf ("%d: %s" , ix , string (b ))
467+ 
468+ 		receivedResponse , streamErr  :=  stream .Recv ()
469+ 		checks .NoError (t , streamErr , "stream.Recv() failed" )
470+ 		if  ! compareChatResponses (expectedResponse , receivedResponse ) {
471+ 			t .Errorf ("Stream response %v is %v, expected %v" , ix , receivedResponse , expectedResponse )
472+ 		}
473+ 	}
474+ 
475+ 	_ , streamErr  :=  stream .Recv ()
476+ 	if  ! errors .Is (streamErr , io .EOF ) {
477+ 		t .Errorf ("stream.Recv() did not return EOF in the end: %v" , streamErr )
478+ 	}
479+ }
480+ 
481+ func  TestCreateChatCompletionStreamWithLogprobs (t  * testing.T ) {
482+ 	client , server , teardown  :=  setupOpenAITestServer ()
483+ 	defer  teardown ()
484+ 	server .RegisterHandler ("/v1/chat/completions" , func (w  http.ResponseWriter , _  * http.Request ) {
485+ 		w .Header ().Set ("Content-Type" , "text/event-stream" )
486+ 
487+ 		// Send test responses 
488+ 		dataBytes  :=  []byte {}
489+ 
490+ 		//nolint:lll 
491+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"1","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":{"content":[],"refusal":null},"finish_reason":null}]}` )... )
492+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
493+ 
494+ 		//nolint:lll 
495+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"2","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":{"content":[{"token":"Hello","logprob":-0.000020458236,"bytes":[72,101,108,108,111],"top_logprobs":[]}],"refusal":null},"finish_reason":null}]}` )... )
496+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
497+ 
498+ 		//nolint:lll 
499+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"3","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{"content":" World"},"logprobs":{"content":[{"token":" World","logprob":-0.00055303273,"bytes":[32,87,111,114,108,100],"top_logprobs":[]}],"refusal":null},"finish_reason":null}]}` )... )
500+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
501+ 
502+ 		//nolint:lll 
503+ 		dataBytes  =  append (dataBytes , []byte (`data: {"id":"4","object":"chat.completion.chunk","created":1729585728,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_d9767fc5b9","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}` )... )
504+ 		dataBytes  =  append (dataBytes , []byte ("\n \n " )... )
505+ 
506+ 		dataBytes  =  append (dataBytes , []byte ("data: [DONE]\n \n " )... )
507+ 
508+ 		_ , err  :=  w .Write (dataBytes )
509+ 		checks .NoError (t , err , "Write error" )
510+ 	})
511+ 
512+ 	stream , err  :=  client .CreateChatCompletionStream (context .Background (), openai.ChatCompletionRequest {
513+ 		MaxTokens : 2000 ,
514+ 		Model :     openai .GPT3Dot5Turbo ,
515+ 		Messages : []openai.ChatCompletionMessage {
516+ 			{
517+ 				Role :    openai .ChatMessageRoleUser ,
518+ 				Content : "Hello!" ,
519+ 			},
520+ 		},
521+ 		Stream : true ,
522+ 	})
523+ 	checks .NoError (t , err , "CreateCompletionStream returned error" )
524+ 	defer  stream .Close ()
525+ 
526+ 	expectedResponses  :=  []openai.ChatCompletionStreamResponse {
527+ 		{
528+ 			ID :                "1" ,
529+ 			Object :            "chat.completion.chunk" ,
530+ 			Created :           1729585728 ,
531+ 			Model :             openai .GPT4oMini20240718 ,
532+ 			SystemFingerprint : "fp_d9767fc5b9" ,
533+ 			Choices : []openai.ChatCompletionStreamChoice {
534+ 				{
535+ 					Index : 0 ,
536+ 					Delta : openai.ChatCompletionStreamChoiceDelta {},
537+ 					Logprobs : & openai.ChatCompletionStreamChoiceLogprobs {
538+ 						Content : []openai.ChatCompletionTokenLogprob {},
539+ 					},
540+ 				},
541+ 			},
542+ 		},
543+ 		{
544+ 			ID :                "2" ,
545+ 			Object :            "chat.completion.chunk" ,
546+ 			Created :           1729585728 ,
547+ 			Model :             openai .GPT4oMini20240718 ,
548+ 			SystemFingerprint : "fp_d9767fc5b9" ,
549+ 			Choices : []openai.ChatCompletionStreamChoice {
550+ 				{
551+ 					Index : 0 ,
552+ 					Delta : openai.ChatCompletionStreamChoiceDelta {
553+ 						Content : "Hello" ,
554+ 					},
555+ 					Logprobs : & openai.ChatCompletionStreamChoiceLogprobs {
556+ 						Content : []openai.ChatCompletionTokenLogprob {
557+ 							{
558+ 								Token :       "Hello" ,
559+ 								Logprob :     - 0.000020458236 ,
560+ 								Bytes :       []int64 {72 , 101 , 108 , 108 , 111 },
561+ 								TopLogprobs : []openai.ChatCompletionTokenLogprobTopLogprob {},
562+ 							},
563+ 						},
564+ 					},
565+ 				},
566+ 			},
567+ 		},
568+ 		{
569+ 			ID :                "3" ,
570+ 			Object :            "chat.completion.chunk" ,
571+ 			Created :           1729585728 ,
572+ 			Model :             openai .GPT4oMini20240718 ,
573+ 			SystemFingerprint : "fp_d9767fc5b9" ,
574+ 			Choices : []openai.ChatCompletionStreamChoice {
575+ 				{
576+ 					Index : 0 ,
577+ 					Delta : openai.ChatCompletionStreamChoiceDelta {
578+ 						Content : " World" ,
579+ 					},
580+ 					Logprobs : & openai.ChatCompletionStreamChoiceLogprobs {
581+ 						Content : []openai.ChatCompletionTokenLogprob {
582+ 							{
583+ 								Token :       " World" ,
584+ 								Logprob :     - 0.00055303273 ,
585+ 								Bytes :       []int64 {32 , 87 , 111 , 114 , 108 , 100 },
586+ 								TopLogprobs : []openai.ChatCompletionTokenLogprobTopLogprob {},
587+ 							},
588+ 						},
589+ 					},
590+ 				},
591+ 			},
592+ 		},
593+ 		{
594+ 			ID :                "4" ,
595+ 			Object :            "chat.completion.chunk" ,
596+ 			Created :           1729585728 ,
597+ 			Model :             openai .GPT4oMini20240718 ,
598+ 			SystemFingerprint : "fp_d9767fc5b9" ,
599+ 			Choices : []openai.ChatCompletionStreamChoice {
600+ 				{
601+ 					Index :        0 ,
602+ 					Delta :        openai.ChatCompletionStreamChoiceDelta {},
603+ 					FinishReason : "stop" ,
604+ 				},
605+ 			},
606+ 		},
607+ 	}
608+ 
609+ 	for  ix , expectedResponse  :=  range  expectedResponses  {
610+ 		b , _  :=  json .Marshal (expectedResponse )
611+ 		t .Logf ("%d: %s" , ix , string (b ))
612+ 
613+ 		receivedResponse , streamErr  :=  stream .Recv ()
614+ 		checks .NoError (t , streamErr , "stream.Recv() failed" )
615+ 		if  ! compareChatResponses (expectedResponse , receivedResponse ) {
616+ 			t .Errorf ("Stream response %v is %v, expected %v" , ix , receivedResponse , expectedResponse )
617+ 		}
618+ 	}
619+ 
620+ 	_ , streamErr  :=  stream .Recv ()
621+ 	if  ! errors .Is (streamErr , io .EOF ) {
622+ 		t .Errorf ("stream.Recv() did not return EOF in the end: %v" , streamErr )
623+ 	}
624+ }
625+ 
361626func  TestAzureCreateChatCompletionStreamRateLimitError (t  * testing.T ) {
362627	wantCode  :=  "429" 
363628	wantMessage  :=  "Requests to the Creates a completion for the chat message Operation under Azure OpenAI API "  + 
0 commit comments