Add refusal field to ChatCompletionMessage and related classes
- Updated OpenAiChatModel, OpenAiApi, and OpenAiStreamFunctionCallingHelper to include the `refusal` field in metadata. - Adjusted constructors and methods to handle the new `refusal` attribute. - Modified related tests to account for the new `refusal` field. - Add the refusal field value to the Spring AI AssistantMessage metadata Resolves #1178
This commit is contained in:
committed by
Christian Tzolov
parent
e2c5208e3e
commit
866b262cdd
@@ -241,12 +241,13 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
|
||||
|
||||
List<Generation> generations = choices.stream().map(choice -> {
|
||||
// @formatter:off
|
||||
Map<String, Object> metadata = Map.of(
|
||||
"id", chatCompletion.id() != null ? chatCompletion.id() : "",
|
||||
"role", choice.message().role() != null ? choice.message().role().name() : "",
|
||||
"index", choice.index(),
|
||||
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "");
|
||||
// @formatter:on
|
||||
Map<String, Object> metadata = Map.of(
|
||||
"id", chatCompletion.id() != null ? chatCompletion.id() : "",
|
||||
"role", choice.message().role() != null ? choice.message().role().name() : "",
|
||||
"index", choice.index(),
|
||||
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "",
|
||||
"refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "");
|
||||
// @formatter:on
|
||||
return buildGeneration(choice, metadata);
|
||||
}).toList();
|
||||
|
||||
@@ -313,7 +314,8 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
|
||||
"id", chatCompletion2.id(),
|
||||
"role", roleMap.getOrDefault(id, ""),
|
||||
"index", choice.index(),
|
||||
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "");
|
||||
"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "",
|
||||
"refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "");
|
||||
|
||||
return buildGeneration(choice, metadata);
|
||||
}).toList();
|
||||
@@ -453,7 +455,7 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
|
||||
}).toList();
|
||||
}
|
||||
return List.of(new ChatCompletionMessage(assistantMessage.getContent(),
|
||||
ChatCompletionMessage.Role.ASSISTANT, null, null, toolCalls));
|
||||
ChatCompletionMessage.Role.ASSISTANT, null, null, toolCalls, null));
|
||||
}
|
||||
else if (message.getMessageType() == MessageType.TOOL) {
|
||||
ToolResponseMessage toolMessage = (ToolResponseMessage) message;
|
||||
@@ -466,7 +468,7 @@ public class OpenAiChatModel extends AbstractToolCallSupport implements ChatMode
|
||||
return toolMessage.getResponses()
|
||||
.stream()
|
||||
.map(tr -> new ChatCompletionMessage(tr.responseData(), ChatCompletionMessage.Role.TOOL, tr.name(),
|
||||
tr.id(), null))
|
||||
tr.id(), null, null))
|
||||
.toList();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -560,7 +560,8 @@ public class OpenAiApi {
|
||||
@JsonProperty("role") Role role,
|
||||
@JsonProperty("name") String name,
|
||||
@JsonProperty("tool_call_id") String toolCallId,
|
||||
@JsonProperty("tool_calls") List<ToolCall> toolCalls) {// @formatter:on
|
||||
@JsonProperty("tool_calls") List<ToolCall> toolCalls,
|
||||
@JsonProperty("refusal") String refusal) {// @formatter:on
|
||||
|
||||
/**
|
||||
* Get message content as String.
|
||||
@@ -582,7 +583,7 @@ public class OpenAiApi {
|
||||
* @param role The role of the author of this message.
|
||||
*/
|
||||
public ChatCompletionMessage(Object content, Role role) {
|
||||
this(content, role, null, null, null);
|
||||
this(content, role, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,6 +91,7 @@ public class OpenAiStreamFunctionCallingHelper {
|
||||
role = (role != null ? role : Role.ASSISTANT); // default to ASSISTANT (if null
|
||||
String name = (current.name() != null ? current.name() : previous.name());
|
||||
String toolCallId = (current.toolCallId() != null ? current.toolCallId() : previous.toolCallId());
|
||||
String refusal = (current.refusal() != null ? current.refusal() : previous.refusal());
|
||||
|
||||
List<ToolCall> toolCalls = new ArrayList<>();
|
||||
ToolCall lastPreviousTooCall = null;
|
||||
@@ -120,7 +121,7 @@ public class OpenAiStreamFunctionCallingHelper {
|
||||
toolCalls.add(lastPreviousTooCall);
|
||||
}
|
||||
}
|
||||
return new ChatCompletionMessage(content, role, name, toolCallId, toolCalls);
|
||||
return new ChatCompletionMessage(content, role, name, toolCallId, toolCalls, refusal);
|
||||
}
|
||||
|
||||
private ToolCall merge(ToolCall previous, ToolCall current) {
|
||||
|
||||
@@ -122,7 +122,7 @@ public class OpenAiApiToolFunctionCallIT {
|
||||
|
||||
// extend conversation with function response.
|
||||
messages.add(new ChatCompletionMessage("" + weatherResponse.temp() + weatherRequest.unit(),
|
||||
Role.TOOL, functionName, toolCall.id(), null));
|
||||
Role.TOOL, functionName, toolCall.id(), null, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user