Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Inference API] Make message content optional in unified API #118998

Merged
merged 6 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,12 @@ public record Message(Content content, String role, @Nullable String name, @Null
);

static {
PARSER.declareField(constructorArg(), (p, c) -> parseContent(p), new ParseField("content"), ObjectParser.ValueType.VALUE_ARRAY);
PARSER.declareField(
optionalConstructorArg(),
maxhniebergall marked this conversation as resolved.
Show resolved Hide resolved
(p, c) -> parseContent(p),
new ParseField("content"),
ObjectParser.ValueType.VALUE_ARRAY
);
PARSER.declareString(constructorArg(), new ParseField("role"));
PARSER.declareString(optionalConstructorArg(), new ParseField("name"));
PARSER.declareString(optionalConstructorArg(), new ParseField("tool_call_id"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
}
builder.endArray();
}
case null -> {
// do nothing
}
}

builder.field(ROLE_FIELD, message.role());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,124 +702,6 @@ public void testSerializationWithBooleanFields() throws IOException {
assertJsonEquals(expectedJsonFalse, jsonStringFalse);
}

// 9. Serialization with Missing Required Fields
maxhniebergall marked this conversation as resolved.
Show resolved Hide resolved
// Test with missing required fields to ensure appropriate exceptions are thrown.
public void testSerializationWithMissingRequiredFields() {
// Create a message with missing content (required field)
UnifiedCompletionRequest.Message message = new UnifiedCompletionRequest.Message(
null, // missing content
OpenAiUnifiedChatCompletionRequestEntity.USER_FIELD,
null,
null,
null
);
var messageList = new ArrayList<UnifiedCompletionRequest.Message>();
messageList.add(message);
// Create the unified request
UnifiedCompletionRequest unifiedRequest = new UnifiedCompletionRequest(
messageList,
null, // model
null, // maxCompletionTokens
null, // stop
null, // temperature
null, // toolChoice
null, // tools
null // topP
);

// Create the unified chat input
UnifiedChatInput unifiedChatInput = new UnifiedChatInput(unifiedRequest, true);

OpenAiChatCompletionModel model = createChatCompletionModel("test-endpoint", "organizationId", "api-key", "model-name", null);

// Create the entity
OpenAiUnifiedChatCompletionRequestEntity entity = new OpenAiUnifiedChatCompletionRequestEntity(unifiedChatInput, model);

// Attempt to serialize to XContent and expect an exception
try {
XContentBuilder builder = JsonXContent.contentBuilder();
entity.toXContent(builder, ToXContent.EMPTY_PARAMS);
fail("Expected an exception due to missing required fields");
} catch (NullPointerException | IOException e) {
// Expected exception
}
}

// 10. Serialization with Mixed Valid and Invalid Data
// Test with a mix of valid and invalid data to ensure the serializer handles it gracefully.
public void testSerializationWithMixedValidAndInvalidData() throws IOException {
// Create a valid message
UnifiedCompletionRequest.Message validMessage = new UnifiedCompletionRequest.Message(
new UnifiedCompletionRequest.ContentString("Valid content"),
OpenAiUnifiedChatCompletionRequestEntity.USER_FIELD,
"validName",
"validToolCallId",
Collections.singletonList(
new UnifiedCompletionRequest.ToolCall(
"validId",
new UnifiedCompletionRequest.ToolCall.FunctionField("validArguments", "validFunctionName"),
"validType"
)
)
);

// Create an invalid message with null content
UnifiedCompletionRequest.Message invalidMessage = new UnifiedCompletionRequest.Message(
null, // invalid content
OpenAiUnifiedChatCompletionRequestEntity.USER_FIELD,
"invalidName",
"invalidToolCallId",
Collections.singletonList(
new UnifiedCompletionRequest.ToolCall(
"invalidId",
new UnifiedCompletionRequest.ToolCall.FunctionField("invalidArguments", "invalidFunctionName"),
"invalidType"
)
)
);
var messageList = new ArrayList<UnifiedCompletionRequest.Message>();
messageList.add(validMessage);
messageList.add(invalidMessage);
// Create the unified request with both valid and invalid messages
UnifiedCompletionRequest unifiedRequest = new UnifiedCompletionRequest(
messageList,
"model-name",
100L, // maxCompletionTokens
Collections.singletonList("stop"),
0.9f, // temperature
new UnifiedCompletionRequest.ToolChoiceString("tool_choice"),
Collections.singletonList(
new UnifiedCompletionRequest.Tool(
"type",
new UnifiedCompletionRequest.Tool.FunctionField(
"Fetches the weather in the given location",
"get_weather",
createParameters(),
true
)
)
),
0.8f // topP
);

// Create the unified chat input
UnifiedChatInput unifiedChatInput = new UnifiedChatInput(unifiedRequest, true);

OpenAiChatCompletionModel model = createChatCompletionModel("test-endpoint", "organizationId", "api-key", "model-name", null);

// Create the entity
OpenAiUnifiedChatCompletionRequestEntity entity = new OpenAiUnifiedChatCompletionRequestEntity(unifiedChatInput, model);

// Serialize to XContent and verify
try {
XContentBuilder builder = JsonXContent.contentBuilder();
entity.toXContent(builder, ToXContent.EMPTY_PARAMS);
fail("Expected an exception due to invalid data");
} catch (NullPointerException | IOException e) {
// Expected exception
}
}

public static Map<String, Object> createParameters() {
Map<String, Object> parameters = new LinkedHashMap<>();
parameters.put("type", "object");
Expand Down
Loading