2
2
3
3
import com .fasterxml .jackson .annotation .JsonProperty ;
4
4
import com .fasterxml .jackson .annotation .JsonPropertyDescription ;
5
+ import com .fasterxml .jackson .core .JsonParser ;
5
6
import com .fasterxml .jackson .databind .JsonNode ;
7
+ import com .fasterxml .jackson .databind .ObjectMapper ;
6
8
import com .fasterxml .jackson .databind .node .ObjectNode ;
7
9
import com .theokanning .openai .completion .chat .*;
8
10
import org .junit .jupiter .api .Test ;
9
11
12
+ import java .io .IOException ;
10
13
import java .util .*;
11
14
12
15
import static org .junit .jupiter .api .Assertions .*;
@@ -23,7 +26,7 @@ static class Weather {
23
26
}
24
27
25
28
enum WeatherUnit {
26
- CELSIUS , FAHRENHEIT ;
29
+ CELSIUS , FAHRENHEIT
27
30
}
28
31
29
32
static class WeatherResponse {
@@ -300,4 +303,46 @@ void streamChatCompletionWithDynamicFunctions() {
300
303
assertNotNull (accumulatedMessage .getFunctionCall ().getArguments ().get ("unit" ));
301
304
}
302
305
306
+ @ Test
307
+ void streamChatCompletionWithJsonResponseFormat () {
308
+ final List <ChatMessage > messages = new ArrayList <>();
309
+
310
+ // The system message is deliberately vague in order to not give too much of a direction of how response should look like.
311
+ // The main gist there is that chat competition should always contain JSON content.
312
+ final ChatMessage systemMessage = new ChatMessage (
313
+ ChatMessageRole .SYSTEM .value (),
314
+ "You are a dog and will speak as such - but please do it in JSON."
315
+ );
316
+
317
+ messages .add (systemMessage );
318
+
319
+ ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest
320
+ .builder ()
321
+ .model ("gpt-4-1106-preview" )
322
+ .messages (messages )
323
+ .n (1 )
324
+ .maxTokens (256 )
325
+ .responseFormat (ChatCompletionRequest .ResponseFormat .of ("json_object" ))
326
+ .build ();
327
+
328
+ ChatCompletionResult chatCompletion = service .createChatCompletion (chatCompletionRequest );
329
+
330
+ ChatCompletionChoice chatCompletionChoice = chatCompletion .getChoices ().get (0 );
331
+ String expectedJsonContent = chatCompletionChoice .getMessage ().getContent ();
332
+
333
+ assertTrue (isValidJSON (expectedJsonContent ), "Invalid JSON response:\n \n " + expectedJsonContent );
334
+ }
335
+
336
+ private boolean isValidJSON (String json ) {
337
+ try (final JsonParser parser = new ObjectMapper ().createParser (json )) {
338
+ while (parser .nextToken () != null ) {
339
+ // Just try to read all tokens in order to verify whether this is valid json.
340
+ }
341
+ return true ;
342
+ } catch (IOException ioe ) {
343
+ ioe .printStackTrace ();
344
+ return false ;
345
+ }
346
+ }
347
+
303
348
}
0 commit comments