-
Notifications
You must be signed in to change notification settings - Fork 2
com_cloudurable_jai_model_text_completion_chat
The Message
class represents a message in a chat system.
The ChatRequest
class extends from CommonCompletionRequest
and represents a chat request in a chat system. It is used to generate a response from the model based on a provided chat conversation. The class has various properties that can be set to control the behavior of the chat completion, such as the model to be used, the list of messages forming the conversation, the role of the message author, the content of the message, and additional options like temperature, top_p, completionCount, stream, stop, maxTokens, presencePenalty, frequencyPenalty, and logitBias. By configuring these properties, the class allows for customizable chat completions in a chat system.
ChatChoice
is a class that extends the Choice
class. It represents a chat choice and contains information such as an index, message, and a finish reason.
The ChatResponse
class is a subclass of TextResponse
that represents a chat response. It includes the ID, object, creation time, chat choices, and usage statistics.
The ChatResponseDeserializer
class provides deserialization functionality for the Chat Response for the Open AI API. It takes a string representation of the JSON response and converts it into a ChatResponse
object, which contains the deserialized information.
The class has several helper methods, including deserializeUsage()
, deserializeChoice()
, deserializeMessage()
, deserializeRole()
, and deserializeFinishReason()
, which are used to deserialize specific parts of the JSON response.
Overall, the ChatResponseDeserializer
class provides a convenient way to deserialize the OpenAI API's chat response JSON into a structured Java object, making it easier to work with and access the information contained in the response.
public static ChatResponse deserialize(final String jsonBody) {
//ystem.out.println(jsonBody);
final JsonParser parser = JsonParserBuilder.builder().build();
final ObjectNode objectNode = parser.parse(jsonBody).asObject();
final String id = objectNode.getString("id");
final String object = objectNode.getString("object");
final int createdTime = objectNode.getInt("created");
final Usage usage = DeserializerUtils.deserializeUsage(objectNode.getObjectNode("usage"));
final ArrayNode choicesNode = objectNode.getArrayNode("choices");
final List<ChatChoice> chatChoices = choicesNode.mapObjectNode(ChatResponseDeserializer::deserializeChoice);
return ChatResponse.builder().choices(chatChoices).id(id).usage(usage).object(object).created(Instant.ofEpochSecond(createdTime)).build();
}
The method deserialize
in class com.cloudurable.jai.model.text.completion.chat.ChatResponseDeserializer
is responsible for deserializing a JSON string into a ChatResponse
object.
Here is a step-by-step description of what the method does:
-
It takes a JSON string
jsonBody
as input. -
It creates a
JsonParser
object usingJsonParserBuilder.builder().build()
. -
It parses the
jsonBody
using theparse
method of theJsonParser
, and then casts the result as anObjectNode
. -
It retrieves the value of the "id" field from the
objectNode
and assigns it to the variableid
. -
It retrieves the value of the "object" field from the
objectNode
and assigns it to the variableobject
. -
It retrieves the value of the "created" field from the
objectNode
and assigns it to the variablecreatedTime
. -
It calls the static method
deserializeUsage
from theDeserializerUtils
class and passes theObjectNode
representing the "usage" field ofobjectNode
as an argument. The returnedUsage
object is assigned to the variableusage
. -
It retrieves an
ArrayNode
representing the "choices" field from theobjectNode
. -
It maps each element in the
choicesNode
using themapObjectNode
method, passing thedeserializeChoice
method from the same class as the mapping function. The result is a list ofChatChoice
objects, which is assigned to the variablechatChoices
. -
It constructs and returns a new
ChatResponse
object using thebuilder
pattern. It sets thechoices
field to thechatChoices
list, theid
field toid
, theusage
field tousage
, theobject
field toobject
, and thecreated
field to anInstant
object created from thecreatedTime
value.
That's it! The method deserialize
deserializes the JSON string and returns a ChatResponse
object.
private static Message deserializeMessage(ObjectNode message) {
Message.Builder builder = Message.builder();
if (message.get("content") != null) {
builder.content(message.getString("content"));
}
if (message.get("name") != null) {
builder.name(message.getString("name"));
}
builder.role(deserializeRole(message.getString("role")));
if (message.get("function_call") != null) {
ObjectNode functionCallNode = message.getObjectNode("function_call");
FunctionalCall.Builder funcBuilder = FunctionalCall.builder().name(functionCallNode.getString("name"));
if (functionCallNode.getString("arguments") != null) {
funcBuilder.arguments(JsonParserBuilder.builder().build().parse(functionCallNode.getString("arguments")).getObjectNode());
}
builder.functionCall(funcBuilder.build());
}
return builder.build();
}
The deserializeMessage
method in the ChatResponseDeserializer
class is used to deserialize a JSON object into a Message
object. Here is a step-by-step description of what the method is doing based on the provided code:
- Create a new
Message.Builder
object. - Check if the JSON object has a field named "content". If it does, get the string value of the "content" field and set it as the content of the message using the
builder.content
method. - Check if the JSON object has a field named "name". If it does, get the string value of the "name" field and set it as the name of the message using the
builder.name
method. - Deserialize the "role" field of the JSON object into a
Role
object using thedeserializeRole
method and set it as the role of the message using thebuilder.role
method. - Check if the JSON object has a field named "function_call". If it does, get the JSON object value of the "function_call" field and assign it to the
functionCallNode
variable. - Create a new
FunctionalCall.Builder
object and set its name as the string value of the "name" field of thefunctionCallNode
using theFunctionalCall.builder().name
method. - Check if the "arguments" field of the
functionCallNode
is not null. If it is not null, get its string value, parse it as JSON usingJsonParserBuilder.builder().build().parse
method, and get the resulting JSON object. Set this JSON object as the arguments of the functional call using thefuncBuilder.arguments
method. - Build the functional call object using the
funcBuilder.build()
method. - Set the functional call object as the function call of the message using the
builder.functionCall
method. - Build the message object using the
builder.build()
method. - Return the built message object.
This method takes a JSON object as input and uses various fields of the JSON object to construct a Message
object with optional content, name, role, and function call.
private static Role deserializeRole(final String role) {
switch(role) {
case "system":
return Role.SYSTEM;
case "user":
return Role.USER;
case "assistant":
return Role.ASSISTANT;
case "function":
return Role.FUNCTION;
default:
return Role.OTHER;
}
}
The method deserializeRole
is defined as a private static method in the class com.cloudurable.jai.model.text.completion.chat.ChatResponseDeserializer
. It takes a parameter role
of type String
, and its return type is Role
.
Here is a step-by-step description of what the deserializeRole
method does based on its body:
-
The method starts with a switch statement that checks the value of the
role
parameter. -
If the value of
role
is"system"
, the switch case for"system"
is executed. It returns the valueRole.SYSTEM
. -
If the value of
role
is"user"
, the switch case for"user"
is executed. It returns the valueRole.USER
. -
If the value of
role
is"assistant"
, the switch case for"assistant"
is executed. It returns the valueRole.ASSISTANT
. -
If the value of
role
is"function"
, the switch case for"function"
is executed. It returns the valueRole.FUNCTION
. -
If none of the above switch cases match the value of
role
, the default case is executed. It returns the valueRole.OTHER
. -
The method ends after the switch statement with the default case.
In summary, the deserializeRole
method takes a string input role
and returns a Role
object based on the value of role
. It maps specific string values to corresponding Role
enum values, and for any other string value, it returns Role.OTHER
.
The ChatRequestSerializer
class provides serialization functionality for ChatRequest
objects. It is responsible for converting ChatRequest
objects into a JSON string representation compatible with the OpenAI API. The class contains a single public static method serialize
, which takes a ChatRequest
object as input and returns the serialized JSON string representation.
During the serialization process, the class constructs a JSON body by appending key-value pairs based on the properties of the ChatRequest
object. The StringBuilder is used for efficient string construction. The method handles different data types and applies appropriate formatting for each property, including messages, functions, and logit biases.
In summary, ChatRequestSerializer
enables the conversion of ChatRequest
objects into JSON strings that can be sent to the OpenAI API for chat completion requests.
public static String serialize(ChatRequest chatRequest) {
final JsonSerializer jsonBodyBuilder = new JsonSerializer();
// start JSON request body for an open ai API chat request
jsonBodyBuilder.startObject();
SerializerUtils.outputModel(chatRequest, jsonBodyBuilder);
final List<Message> messages = chatRequest.getMessages();
// start JSON list body for messages
jsonBodyBuilder.startNestedArrayAttribute("messages");
for (Message message : messages) {
jsonBodyBuilder.startNestedObjectElement();
jsonBodyBuilder.addAttribute("role", message.getRole().toString().toLowerCase());
jsonBodyBuilder.addAttribute("content", message.getContent());
if (message.getName() != null) {
jsonBodyBuilder.addAttribute("name", message.getName());
}
jsonBodyBuilder.endObject();
}
jsonBodyBuilder.endArray();
SerializerUtils.outputTextParams(chatRequest, jsonBodyBuilder);
if (chatRequest.getFunctionalCall() == ChatRequest.AUTO) {
jsonBodyBuilder.addAttribute("function_call", "auto");
} else if (chatRequest.getFunctionalCall() == ChatRequest.NONE) {
jsonBodyBuilder.addAttribute("function_call", "none");
} else if (chatRequest.getFunctionalCall() != null) {
final FunctionalCall functionalCall = chatRequest.getFunctionalCall();
jsonBodyBuilder.startNestedObjectAttribute("function_call");
jsonBodyBuilder.addAttribute("name", functionalCall.getName());
if (functionalCall.getArguments() != null) {
jsonBodyBuilder.addAttribute("arguments", functionalCall.getArguments().toString());
}
jsonBodyBuilder.endObject();
}
final List<FunctionDef> functions = chatRequest.getFunctions();
if (functions != null && !functions.isEmpty()) {
jsonBodyBuilder.startNestedArrayAttribute("functions");
for (FunctionDef function : functions) {
jsonBodyBuilder.startNestedObjectElement();
jsonBodyBuilder.addAttribute("name", function.getName());
ObjectParameter parameters = function.getParameters();
writeObjectParameter(jsonBodyBuilder, parameters);
jsonBodyBuilder.endObject();
jsonBodyBuilder.endObject();
}
jsonBodyBuilder.endArray();
}
SerializerUtils.outputCompletionParams(chatRequest, jsonBodyBuilder);
// end JSON request body for an open ai API chat request
jsonBodyBuilder.endObject();
String json = jsonBodyBuilder.toString();
//ystem.out.println(json);
return json;
}
The serialize
method in class com.cloudurable.jai.model.text.completion.chat.ChatRequestSerializer
is responsible for converting a ChatRequest object into a JSON string.
Here is a step-by-step description of what this method does based on its body:
- Create a new
JsonSerializer
object namedjsonBodyBuilder
. - Start the JSON request body for an open AI API chat request by calling
startObject()
onjsonBodyBuilder
. - Use the
SerializerUtils.outputModel
method to output the chatRequest object to thejsonBodyBuilder
. - Get the list of messages from the chatRequest object.
- Start the JSON list body for messages by calling
startNestedArrayAttribute("messages")
onjsonBodyBuilder
. - Iterate over each message in the messages list.
- Start a nested JSON object element by calling
startNestedObjectElement()
onjsonBodyBuilder
. - Add the "role" attribute with the lowercase value of
message.getRole().toString()
by callingaddAttribute("role", message.getRole().toString().toLowerCase())
onjsonBodyBuilder
. - Add the "content" attribute with the value of
message.getContent()
by callingaddAttribute("content", message.getContent())
onjsonBodyBuilder
. - If the message has a name, add the "name" attribute with its value by calling
addAttribute("name", message.getName())
onjsonBodyBuilder
. - End the nested JSON object by calling
endObject()
onjsonBodyBuilder
.
- Start a nested JSON object element by calling
- End the JSON list body for messages by calling
endArray()
onjsonBodyBuilder
. - Use the
SerializerUtils.outputTextParams
method to output text parameters from the chatRequest object to thejsonBodyBuilder
. - Check if the functionalCall of the chatRequest is "AUTO", "NONE", or not null.
- If the functionalCall is "AUTO", add the "function_call" attribute with the value "auto" by calling
addAttribute("function_call", "auto")
onjsonBodyBuilder
. - If the functionalCall is "NONE", add the "function_call" attribute with the value "none" by calling
addAttribute("function_call", "none")
onjsonBodyBuilder
. - If the functionalCall is not null, handle the functionalCall object by doing the following:
- Start a nested JSON object attribute for "function_call" by calling
startNestedObjectAttribute("function_call")
onjsonBodyBuilder
. - Add the "name" attribute with the value of
functionalCall.getName()
by callingaddAttribute("name", functionalCall.getName())
onjsonBodyBuilder
. - If the functionalCall has arguments, add the "arguments" attribute with the string representation of the arguments by calling
addAttribute("arguments", functionalCall.getArguments().toString())
onjsonBodyBuilder
. - End the nested JSON object by calling
endObject()
onjsonBodyBuilder
.
- Start a nested JSON object attribute for "function_call" by calling
- If the functionalCall is "AUTO", add the "function_call" attribute with the value "auto" by calling
- Get the list of functions from the chatRequest object.
- Check if the functions list is not null and not empty.
- If true, start the nested array attribute for "functions" by calling
startNestedArrayAttribute("functions")
onjsonBodyBuilder
. - Iterate over each function in the functions list.
- Start a nested JSON object element by calling
startNestedObjectElement()
onjsonBodyBuilder
. - Add the "name" attribute with the value of
function.getName()
by callingaddAttribute("name", function.getName())
onjsonBodyBuilder
. - Get the parameters object of the function.
- Use the
writeObjectParameter
method to write the parameters to thejsonBodyBuilder
. - End the nested JSON object by calling
endObject()
onjsonBodyBuilder
.
- Start a nested JSON object element by calling
- End the nested array by calling
endArray()
onjsonBodyBuilder
.
- Use the
SerializerUtils.outputCompletionParams
method to output completion parameters from the chatRequest object to thejsonBodyBuilder
. - End the JSON request body for an open AI API chat request by calling
endObject()
onjsonBodyBuilder
. - Convert the JSON body to a string by calling
toString()
onjsonBodyBuilder
and assign it to thejson
variable. - Return the
json
string.
Please note that there is commented-out code in the method that prints the JSON, but it is not part of the serialized output.
public static void writeObjectParameter(JsonSerializer jsonBodyBuilder, ObjectParameter op) {
jsonBodyBuilder.startNestedObjectAttribute("parameters");
jsonBodyBuilder.addAttribute("type", op.getType().toString().toLowerCase());
jsonBodyBuilder.startNestedObjectAttribute("properties");
for (Parameter parameter : op.getProperties()) {
jsonBodyBuilder.startNestedObjectAttribute(parameter.getName());
jsonBodyBuilder.addAttribute("type", parameter.getType().toString().toLowerCase());
if (parameter instanceof EnumParameter) {
jsonBodyBuilder.startNestedArrayAttribute("enum");
for (String enumValue : ((EnumParameter) parameter).getEnumValues()) {
jsonBodyBuilder.addElement(enumValue);
}
jsonBodyBuilder.endArray();
}
jsonBodyBuilder.endObject();
}
jsonBodyBuilder.endObject();
jsonBodyBuilder.startNestedArrayAttribute("required");
for (String req : op.getRequired()) {
jsonBodyBuilder.addElement(req);
}
jsonBodyBuilder.endArray();
}
The writeObjectParameter
method in the ChatRequestSerializer
class is responsible for serializing an ObjectParameter
object and writing its attributes to a JSON body.
Here is the step-by-step description of what this method is doing:
- Start building the nested object attribute "parameters" in the JSON body.
- Add the "type" attribute to indicate the type of the
ObjectParameter
object. - Start building the nested object attribute "properties" in the JSON body.
- Iterate through each
Parameter
object in theop.getProperties()
list. a. Start building the nested object attribute with the parameter name. b. Add the "type" attribute to indicate the type of the parameter. c. If the parameter is an instance ofEnumParameter
, start building the nested array attribute "enum". d. Iterate through each enum value in thegetEnumValues()
list of theEnumParameter
. e. Add each enum value as an element in the "enum" array. f. End the object attribute for the parameter. - End the object attribute for "properties".
- Start building the nested array attribute "required".
- Iterate through each required attribute in the
op.getRequired()
list. a. Add each required attribute as an element in the "required" array. - End the array attribute for "required".
By following these steps, the writeObjectParameter
method will produce a JSON body that represents the attributes of the ObjectParameter
object.
- Java Open AI Client
- Using ChatGpt embeddings and hyde to improve search results
- Anthropics Claude Chatbot Gets Upgrade
- Elon Musks XAi new frontier for artificial intelligence
- Using Mockito to test JAI Java Open AI Client
- Fine tuning journey with Open AI API
- Using Open AI to create callback functions, the basis for plugins
- Using Java Open AI Client Async
- Fastest Java JSON Parser
- Java Open AI API Client on Github
- Medium: Introducing Java Open AI Client
- Medium: Using ChatGPT, Embeddings, and HyDE to Improve Search Results