88import static com .sap .ai .sdk .foundationmodels .openai .model2 .CreateChatCompletionStreamResponse .ObjectEnum .CHAT_COMPLETION_CHUNK ;
99import static org .assertj .core .api .Assertions .assertThat ;
1010import static org .assertj .core .api .Assertions .assertThatThrownBy ;
11+ import static org .assertj .core .api .InstanceOfAssertFactories .MAP ;
1112import static org .mockito .ArgumentMatchers .any ;
1213import static org .mockito .Mockito .doReturn ;
1314import static org .mockito .Mockito .mock ;
1617import static org .mockito .Mockito .when ;
1718
1819import com .fasterxml .jackson .core .JsonParseException ;
20+ import com .fasterxml .jackson .databind .ObjectMapper ;
1921import com .github .tomakehurst .wiremock .junit5 .WireMockRuntimeInfo ;
2022import com .github .tomakehurst .wiremock .junit5 .WireMockTest ;
2123import com .github .tomakehurst .wiremock .stubbing .Scenario ;
2527import com .sap .ai .sdk .foundationmodels .openai .model2 .ChatCompletionRequestUserMessageContent ;
2628import com .sap .ai .sdk .foundationmodels .openai .model2 .CompletionUsage ;
2729import com .sap .ai .sdk .foundationmodels .openai .model2 .ContentFilterChoiceResults ;
30+ import com .sap .ai .sdk .foundationmodels .openai .model2 .ContentFilterPromptResults ;
2831import com .sap .ai .sdk .foundationmodels .openai .model2 .CreateChatCompletionRequest ;
2932import com .sap .ai .sdk .foundationmodels .openai .model2 .CreateChatCompletionResponse ;
3033import com .sap .ai .sdk .foundationmodels .openai .model2 .CreateChatCompletionResponseChoicesInner ;
6265
6366@ WireMockTest
6467class OpenAiClientTest {
68+ private static final ObjectMapper MAPPER = new ObjectMapper ();
6569 private static OpenAiClient client ;
6670 private final Function <String , InputStream > fileLoader =
6771 filename -> Objects .requireNonNull (getClass ().getClassLoader ().getResourceAsStream (filename ));
@@ -242,7 +246,8 @@ void chatCompletion(@Nonnull final Callable<CreateChatCompletionResponse> reques
242246
243247 assertThat (result .getPromptFilterResults ()).hasSize (1 );
244248 assertThat (result .getPromptFilterResults ().get (0 ).getPromptIndex ()).isEqualTo (0 );
245- /*OpenAiContentFilterPromptResults promptFilterResults = result.getPromptFilterResults().get(0).getContentFilterResults();
249+ ContentFilterPromptResults promptFilterResults =
250+ result .getPromptFilterResults ().get (0 ).getContentFilterResults ();
246251 assertThat (promptFilterResults ).isNotNull ();
247252 assertThat (promptFilterResults .getSexual ()).isNotNull ();
248253 assertThat (promptFilterResults .getSexual ().isFiltered ()).isFalse ();
@@ -258,7 +263,7 @@ void chatCompletion(@Nonnull final Callable<CreateChatCompletionResponse> reques
258263 assertThat (promptFilterResults .getSelfHarm ().isFiltered ()).isFalse ();
259264 assertThat (promptFilterResults .getProfanity ()).isNull ();
260265 assertThat (promptFilterResults .getError ()).isNull ();
261- assertThat(promptFilterResults.getJailbreak()).isNull();*/
266+ assertThat (promptFilterResults .getJailbreak ()).isNull ();
262267
263268 assertThat (result .getChoices ()).hasSize (1 );
264269 CreateChatCompletionResponseChoicesInner choice = result .getChoices ().get (0 );
@@ -503,10 +508,16 @@ void streamChatCompletionDeltas() throws IOException {
503508
504509 try (Stream <OpenAiChatCompletionDelta > stream = client .streamChatCompletionDeltas (request )) {
505510
506- CompletionUsage totalOutput = new CompletionUsage ();
507511 final List <OpenAiChatCompletionDelta > deltaList = stream .toList ();
508- // stream.peek(o -> usage.setCompletionTokens(o.getSystemFingerprint()).set
509- // ::addDelta).toList();
512+ final var delta0 = (CreateChatCompletionResponse ) deltaList .get (0 ).getOriginalResponse ();
513+ final var delta1 =
514+ (CreateChatCompletionStreamResponse ) deltaList .get (1 ).getOriginalResponse ();
515+ final var delta2 =
516+ (CreateChatCompletionStreamResponse ) deltaList .get (2 ).getOriginalResponse ();
517+ final var delta3 =
518+ (CreateChatCompletionStreamResponse ) deltaList .get (3 ).getOriginalResponse ();
519+ final var delta4 =
520+ (CreateChatCompletionStreamResponse ) deltaList .get (4 ).getOriginalResponse ();
510521
511522 assertThat (deltaList ).hasSize (5 );
512523 // the first two and the last delta don't have any content
@@ -516,94 +527,49 @@ void streamChatCompletionDeltas() throws IOException {
516527 assertThat (deltaList .get (3 ).getDeltaContent ()).isEqualTo ("!" );
517528 assertThat (deltaList .get (4 ).getDeltaContent ()).isEqualTo ("" );
518529
519- assertThat (
520- ((CreateChatCompletionResponse ) deltaList .get (0 ).getOriginalResponse ())
521- .getSystemFingerprint ())
522- .isNull ();
523- assertThat (
524- ((CreateChatCompletionStreamResponse ) deltaList .get (1 ).getOriginalResponse ())
525- .getSystemFingerprint ())
526- .isEqualTo ("fp_e49e4201a9" );
527- assertThat (
528- ((CreateChatCompletionStreamResponse ) deltaList .get (2 ).getOriginalResponse ())
529- .getSystemFingerprint ())
530- .isEqualTo ("fp_e49e4201a9" );
531- assertThat (
532- ((CreateChatCompletionStreamResponse ) deltaList .get (3 ).getOriginalResponse ())
533- .getSystemFingerprint ())
534- .isEqualTo ("fp_e49e4201a9" );
535- assertThat (
536- ((CreateChatCompletionStreamResponse ) deltaList .get (4 ).getOriginalResponse ())
537- .getSystemFingerprint ())
538- .isEqualTo ("fp_e49e4201a9" );
539-
540- assertThat (
541- ((CreateChatCompletionResponse ) deltaList .get (0 ).getOriginalResponse ()).getUsage ())
542- .isNull ();
543- assertThat (
544- ((CreateChatCompletionStreamResponse ) deltaList .get (1 ).getOriginalResponse ())
545- .getCustomField ("usage" ))
546- .isNull ();
547- assertThat (
548- ((CreateChatCompletionStreamResponse ) deltaList .get (2 ).getOriginalResponse ())
549- .getCustomField ("usage" ))
550- .isNull ();
551- assertThat (
552- ((CreateChatCompletionStreamResponse ) deltaList .get (3 ).getOriginalResponse ())
553- .getCustomField ("usage" ))
554- .isNull ();
555- final var usage =
556- ((CreateChatCompletionStreamResponse ) deltaList .get (4 ).getOriginalResponse ())
557- .getCustomField ("usage" );
558- assertThat (usage ).isNotNull ();
559- assertThat (((Map <?, ?>) usage ).get ("completion_tokens" )).isEqualTo (607 );
560- assertThat (((Map <?, ?>) usage ).get ("prompt_tokens" )).isEqualTo (21 );
561- assertThat (((Map <?, ?>) usage ).get ("total_tokens" )).isEqualTo (628 );
562-
563- assertThat (
564- ((CreateChatCompletionResponse ) deltaList .get (0 ).getOriginalResponse ())
565- .getChoices ())
566- .isEmpty ();
567- assertThat (
568- ((CreateChatCompletionStreamResponse ) deltaList .get (1 ).getOriginalResponse ())
569- .getChoices ())
570- .hasSize (1 );
571- assertThat (
572- ((CreateChatCompletionStreamResponse ) deltaList .get (2 ).getOriginalResponse ())
573- .getChoices ())
574- .hasSize (1 );
575- assertThat (
576- ((CreateChatCompletionStreamResponse ) deltaList .get (3 ).getOriginalResponse ())
577- .getChoices ())
578- .hasSize (1 );
579- assertThat (
580- ((CreateChatCompletionStreamResponse ) deltaList .get (4 ).getOriginalResponse ())
581- .getChoices ())
582- .hasSize (1 );
530+ assertThat (delta0 .getSystemFingerprint ()).isNull ();
531+ assertThat (delta1 .getSystemFingerprint ()).isEqualTo ("fp_e49e4201a9" );
532+ assertThat (delta2 .getSystemFingerprint ()).isEqualTo ("fp_e49e4201a9" );
533+ assertThat (delta3 .getSystemFingerprint ()).isEqualTo ("fp_e49e4201a9" );
534+ assertThat (delta4 .getSystemFingerprint ()).isEqualTo ("fp_e49e4201a9" );
535+
536+ assertThat (delta0 .getUsage ()).isNull ();
537+ assertThat (delta1 .getCustomField ("usage" )).isNull ();
538+ assertThat (delta2 .getCustomField ("usage" )).isNull ();
539+ assertThat (delta3 .getCustomField ("usage" )).isNull ();
540+ final Map <?, ?> delta4UsageRaw = (Map <?, ?>) delta4 .getCustomField ("usage" );
541+ final var delta4Usage = MAPPER .convertValue (delta4UsageRaw , CompletionUsage .class );
542+ assertThat (delta4Usage ).isNotNull ();
543+ assertThat (delta4Usage .getCompletionTokens ()).isEqualTo (607 );
544+ assertThat (delta4Usage .getPromptTokens ()).isEqualTo (21 );
545+ assertThat (delta4Usage .getTotalTokens ()).isEqualTo (628 );
546+
547+ // delta 0
583548
584- final var delta0 = (CreateChatCompletionResponse ) deltaList .get (0 ).getOriginalResponse ();
585549 assertThat (delta0 .getId ()).isEqualTo ("" );
586550 assertThat (delta0 .getCreated ()).isEqualTo (0 );
587551 assertThat (delta0 .getModel ()).isEqualTo ("" );
588552 assertThat (delta0 .getObject ()).isEqualTo (UNKNOWN_DEFAULT_OPEN_API );
589- // assertThat(delta0.getUsage()).isNull();
553+ assertThat (delta0 .getUsage ()).isNull ();
590554 assertThat (delta0 .getChoices ()).isEmpty ();
591555 // prompt filter results are only present in delta 0
592- // assertThat(delta0.getPromptFilterResults()).isNotNull();
593- // assertThat(delta0.getPromptFilterResults().get(0).getPromptIndex()).isEqualTo(0);
594- // final var promptFilter0 =
595- // delta0.getPromptFilterResults().get(0).getContentFilterResults();
596- // assertThat(promptFilter0).isNotNull();
597- // assertFilter(promptFilter0);
556+ assertThat (delta0 .getPromptFilterResults ()).isNotNull ();
557+ assertThat (delta0 .getPromptFilterResults ().get (0 ).getPromptIndex ()).isEqualTo (0 );
558+ final var promptFilter0 = delta0 .getPromptFilterResults ().get (0 ).getContentFilterResults ();
559+ assertThat (promptFilter0 ).isNotNull ();
560+ assertFilter (promptFilter0 );
598561
599- final var delta2 =
600- (CreateChatCompletionStreamResponse ) deltaList .get (2 ).getOriginalResponse ();
562+ // delta 1
563+ assertThat (delta1 .getChoices ()).hasSize (1 );
564+
565+ // delta 2
601566 assertThat (delta2 .getId ()).isEqualTo ("chatcmpl-A16EvnkgEm6AdxY0NoOmGPjsJucQ1" );
602567 assertThat (delta2 .getCreated ()).isEqualTo (1724825677 );
603568 assertThat (delta2 .getModel ()).isEqualTo ("gpt-35-turbo" );
604569 assertThat (delta2 .getObject ()).isEqualTo (CHAT_COMPLETION_CHUNK );
605- // assertThat(delta2.getUsage()).isNull();
606- // assertThat(delta2.getPromptFilterResults()).isNull();
570+ assertThat (delta2 .getCustomField ("usage" )).isNull ();
571+ assertThat (delta2 .getCustomFieldNames ()).doesNotContain ("prompt_filter_results" );
572+ assertThat (delta2 .getChoices ()).hasSize (1 );
607573 final var choices2 = delta2 .getChoices ().get (0 );
608574 assertThat (choices2 .getIndex ()).isEqualTo (0 );
609575 assertThat (choices2 .getFinishReason ()).isNull ();
@@ -612,14 +578,18 @@ void streamChatCompletionDeltas() throws IOException {
612578 assertThat (choices2 .getDelta ().getRole ()).isNull ();
613579 assertThat (choices2 .getDelta ().getContent ()).isEqualTo ("Sure" );
614580 assertThat (choices2 .getDelta ().getToolCalls ()).isNotNull ().isEmpty ();
615- // final var filter2 = choices2.getContentFilterResults();
616- // assertFilter(filter2);
581+ final Map <?, ?> filter2raw = (Map <?, ?>) choices2 .getCustomField ("content_filter_results" );
582+ final var filter2 = MAPPER .convertValue (filter2raw , ContentFilterPromptResults .class );
583+ assertFilter (filter2 );
617584
618- final var delta3 = deltaList .get (3 );
619- assertThat (delta3 .getDeltaContent ()).isEqualTo ("!" );
585+ // delta 3
620586
621- final var delta4 =
622- (CreateChatCompletionStreamResponse ) deltaList .get (4 ).getOriginalResponse ();
587+ assertThat (delta3 .getChoices ()).hasSize (1 );
588+ assertThat (deltaList .get (3 ).getDeltaContent ()).isEqualTo ("!" );
589+
590+ // delta 4
591+
592+ assertThat (delta4 .getChoices ()).hasSize (1 );
623593 final var delta4Choice = delta4 .getChoices ().get (0 );
624594 assertThat (delta4Choice .getFinishReason ())
625595 .isEqualTo (CreateChatCompletionStreamResponseChoicesInner .FinishReasonEnum .STOP );
@@ -628,34 +598,30 @@ void streamChatCompletionDeltas() throws IOException {
628598 assertThat (delta4Choice .getDelta ().getRole ()).isNull ();
629599 assertThat (delta4Choice .getDelta ().getContent ()).isNull ();
630600 assertThat (delta4Choice .getDelta ().getToolCalls ()).isEmpty ();
631- // assertThat(totalOutput.getChoices()).hasSize(1);
632- // final var choice = totalOutput.getChoices().get(0);
633- // assertThat(choice.getFinishReason()).isEqualTo("stop");
634- // assertFilter(getContentFilterResults()); // TODO
635- // assertThat(choice.getFinishReason()).isEqualTo("stop");
636- // assertThat(choice.getDelta()).isNotNull();
637- // assertThat(choice.getDelta().getRole()).isEqualTo("assistant");
638- // assertThat(choice.getDelta().getContent()).isEqualTo("Sure!");
639- // assertThat(choice.getDelta().getToolCalls()).isNull();
640- // assertThat(totalOutput.getId()).isEqualTo("chatcmpl-A16EvnkgEm6AdxY0NoOmGPjsJucQ1");
641- // assertThat(totalOutput.getCreated()).isEqualTo(1724825677);
642- // assertThat(totalOutput.getModel()).isEqualTo("gpt-35-turbo");
643- // assertThat(totalOutput.getObject()).isEqualTo("chat.completion.chunk");
644- // final var totalUsage = totalOutput.getUsage();
645- // assertThat(totalUsage).isNotNull();
646- // assertThat(totalUsage.getCompletionTokens()).isEqualTo(607);
647- // assertThat(totalUsage.getPromptTokens()).isEqualTo(21);
648- // assertThat(totalUsage.getTotalTokens()).isEqualTo(628);
649- // assertThat(totalOutput.getSystemFingerprint()).isEqualTo("fp_e49e4201a9");
650- // assertThat(totalOutput.getPromptFilterResults()).isNotNull();
651- // assertFilter(totalOutput.getPromptFilterResults().get(0).getContentFilterResults());
601+ assertThat (delta4 .getChoices ()).hasSize (1 );
602+ final var choice = delta4 .getChoices ().get (0 );
603+ assertThat (choice .getFinishReason ())
604+ .isEqualTo (CreateChatCompletionStreamResponseChoicesInner .FinishReasonEnum .STOP );
605+ final Map <?, ?> filterRaw = (Map <?, ?>) choice .getCustomField ("content_filter_results" );
606+ assertThat (filterRaw ).isEmpty ();
607+ assertThat (choice .getDelta ()).isNotNull ();
608+ assertThat (choice .getDelta ().getRole ()).isNull ();
609+ assertThat (choice .getDelta ().getContent ()).isNull ();
610+ assertThat (choice .getDelta ().getToolCalls ()).isNotNull ().isEmpty ();
611+ assertThat (delta4 .getId ()).isEqualTo ("chatcmpl-A16EvnkgEm6AdxY0NoOmGPjsJucQ1" );
612+ assertThat (delta4 .getCreated ()).isEqualTo (1724825677 );
613+ assertThat (delta4 .getModel ()).isEqualTo ("gpt-35-turbo" );
614+ assertThat (delta4 .getObject ()).isEqualTo (CHAT_COMPLETION_CHUNK );
615+ assertThat (choice .getCustomField ("content_filter_results" )).asInstanceOf (MAP ).isEmpty ();
616+ assertThat (delta4 .getSystemFingerprint ()).isEqualTo ("fp_e49e4201a9" );
617+ assertThat (delta4 .getCustomFieldNames ()).doesNotContain ("prompt_filter_results" );
652618 }
653619
654620 Mockito .verify (inputStream , times (1 )).close ();
655621 }
656622 }
657623
658- /* void assertFilter(OpenAiContentFilterPromptResults filter) {
624+ void assertFilter (ContentFilterPromptResults filter ) {
659625 assertThat (filter ).isNotNull ();
660626 assertThat (filter .getHate ()).isNotNull ();
661627 assertThat (filter .getHate ().isFiltered ()).isFalse ();
@@ -672,5 +638,5 @@ void streamChatCompletionDeltas() throws IOException {
672638 assertThat (filter .getJailbreak ()).isNull ();
673639 assertThat (filter .getProfanity ()).isNull ();
674640 assertThat (filter .getError ()).isNull ();
675- }*/
641+ }
676642}
0 commit comments