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:
TarasVovk669
2024-08-07 11:55:31 +02:00
committed by Christian Tzolov
parent e2c5208e3e
commit 866b262cdd
4 changed files with 17 additions and 13 deletions

View File

@@ -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 {

View File

@@ -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);
}
/**

View File

@@ -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) {

View File

@@ -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));
}
}