@@ -358,6 +358,271 @@ func TestCreateChatCompletionStreamRateLimitError(t *testing.T) {
358
358
t .Logf ("%+v\n " , apiErr )
359
359
}
360
360
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
+
361
626
func TestAzureCreateChatCompletionStreamRateLimitError (t * testing.T ) {
362
627
wantCode := "429"
363
628
wantMessage := "Requests to the Creates a completion for the chat message Operation under Azure OpenAI API " +
0 commit comments