Compare commits

..

No commits in common. "bd3267da5ba55568c51f8c3c722df1b0854c8645" and "1ce2658b5535eb9d74d257acc96b95a5c9946c31" have entirely different histories.

7 changed files with 51 additions and 75 deletions

View file

@ -1,6 +1,5 @@
package de.hhhammer.dchat.bot; package de.hhhammer.dchat.bot;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import de.hhhammer.dchat.bot.openai.ChatGPTService; import de.hhhammer.dchat.bot.openai.ChatGPTService;
@ -33,7 +32,7 @@ public class App {
System.exit(1); System.exit(1);
} }
var chatGPTService = new ChatGPTService(openaiApiKey, HttpClient.newHttpClient(), new ObjectMapper()); var chatGPTService = new ChatGPTService(openaiApiKey, HttpClient.newHttpClient());
var config = new HikariConfig(); var config = new HikariConfig();
config.setJdbcUrl(postgresUrl); config.setJdbcUrl(postgresUrl);

View file

@ -21,7 +21,7 @@ public class MessageCreateHandler implements MessageCreateListener {
@Override @Override
public void onMessageCreate(MessageCreateEvent event) { public void onMessageCreate(MessageCreateEvent event) {
Thread.ofVirtual().start(() -> { Thread.ofVirtual().start(() -> {
if (!event.canYouReadContent() || event.getMessageAuthor().isBotUser() || !isNormalOrReplyMessageType(event)) { if (!event.canYouReadContent() || event.getMessageAuthor().isBotUser() || !(event.getMessage().getType() == MessageType.NORMAL || event.getMessage().getType() == MessageType.REPLY)) {
return; return;
} }
if (!this.messageHandler.canHandle(event)) { if (!this.messageHandler.canHandle(event)) {
@ -42,9 +42,4 @@ public class MessageCreateHandler implements MessageCreateListener {
} }
}); });
} }
private boolean isNormalOrReplyMessageType(MessageCreateEvent event) {
MessageType type = event.getMessage().getType();
return type == MessageType.NORMAL || type == MessageType.REPLY;
}
} }

View file

@ -2,7 +2,6 @@ package de.hhhammer.dchat.bot.discord;
import de.hhhammer.dchat.bot.openai.ChatGPTRequestBuilder; import de.hhhammer.dchat.bot.openai.ChatGPTRequestBuilder;
import de.hhhammer.dchat.bot.openai.ChatGPTService; import de.hhhammer.dchat.bot.openai.ChatGPTService;
import de.hhhammer.dchat.bot.openai.MessageContext.ReplyInteraction;
import de.hhhammer.dchat.bot.openai.ResponseException; import de.hhhammer.dchat.bot.openai.ResponseException;
import de.hhhammer.dchat.db.ServerDBService; import de.hhhammer.dchat.db.ServerDBService;
import de.hhhammer.dchat.db.models.server.ServerMessage; import de.hhhammer.dchat.db.models.server.ServerMessage;
@ -11,12 +10,10 @@ import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageReference; import org.javacord.api.entity.message.MessageReference;
import org.javacord.api.entity.message.MessageType; import org.javacord.api.entity.message.MessageType;
import org.javacord.api.event.message.MessageCreateEvent; import org.javacord.api.event.message.MessageCreateEvent;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.List;
public class ServerMessageHandler implements MessageHandler { public class ServerMessageHandler implements MessageHandler {
@ -34,8 +31,16 @@ public class ServerMessageHandler implements MessageHandler {
String content = extractContent(event); String content = extractContent(event);
var serverId = event.getServer().get().getId(); var serverId = event.getServer().get().getId();
var systemMessage = this.serverDBService.getConfig(String.valueOf(serverId)).get().systemMessage(); var systemMessage = this.serverDBService.getConfig(String.valueOf(serverId)).get().systemMessage();
List<ReplyInteraction> messageContext = event.getMessage().getType() == MessageType.REPLY ? getContextMessages(event) : List.of(); var request = event.getMessage().getType() == MessageType.REPLY ?
var request = new ChatGPTRequestBuilder().contextRequest(messageContext, content, systemMessage); new ChatGPTRequestBuilder()
.replyRequest(event.getMessage()
.getMessageReference()
.map(MessageReference::getMessage)
.flatMap(m -> m)
.map(Message::getReadableContent)
.stream().toList(),
content, systemMessage) :
new ChatGPTRequestBuilder().simpleRequest(content, systemMessage);
var response = this.chatGPTService.submit(request); var response = this.chatGPTService.submit(request);
if (response.choices().isEmpty()) { if (response.choices().isEmpty()) {
event.getMessage().reply("No response available"); event.getMessage().reply("No response available");
@ -92,16 +97,4 @@ public class ServerMessageHandler implements MessageHandler {
long ownId = event.getApi().getYourself().getId(); long ownId = event.getApi().getYourself().getId();
return event.getMessageContent().replaceFirst("<" + ownId + "> ", ""); return event.getMessageContent().replaceFirst("<" + ownId + "> ", "");
} }
@NotNull
private List<ReplyInteraction> getContextMessages(MessageCreateEvent event) {
return event.getMessage()
.getMessageReference()
.map(MessageReference::getMessage)
.flatMap(m -> m)
.map(Message::getReadableContent)
.map(ReplyInteraction::new)
.stream()
.toList();
}
} }

View file

@ -2,7 +2,6 @@ package de.hhhammer.dchat.bot.discord;
import de.hhhammer.dchat.bot.openai.ChatGPTRequestBuilder; import de.hhhammer.dchat.bot.openai.ChatGPTRequestBuilder;
import de.hhhammer.dchat.bot.openai.ChatGPTService; import de.hhhammer.dchat.bot.openai.ChatGPTService;
import de.hhhammer.dchat.bot.openai.MessageContext.PreviousInteraction;
import de.hhhammer.dchat.bot.openai.ResponseException; import de.hhhammer.dchat.bot.openai.ResponseException;
import de.hhhammer.dchat.db.UserDBService; import de.hhhammer.dchat.db.UserDBService;
import de.hhhammer.dchat.db.models.user.UserMessage; import de.hhhammer.dchat.db.models.user.UserMessage;
@ -11,7 +10,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.List;
public class UserMessageHandler implements MessageHandler { public class UserMessageHandler implements MessageHandler {
private static final Logger logger = LoggerFactory.getLogger(UserMessageHandler.class); private static final Logger logger = LoggerFactory.getLogger(UserMessageHandler.class);
@ -29,9 +27,9 @@ public class UserMessageHandler implements MessageHandler {
var userId = String.valueOf(event.getMessageAuthor().getId()); var userId = String.valueOf(event.getMessageAuthor().getId());
var config = this.userDBService.getConfig(userId).get(); var config = this.userDBService.getConfig(userId).get();
var systemMessage = config.systemMessage(); var systemMessage = config.systemMessage();
List<PreviousInteraction> context = this.userDBService.getLastMessages(userId, config.contextLength()) var context = this.userDBService.getLastMessages(userId, config.contextLength())
.stream() .stream()
.map(userMessage -> new PreviousInteraction(userMessage.question(), userMessage.answer())) .map(userMessage -> new ChatGPTRequestBuilder.PreviousInteraction(userMessage.question(), userMessage.answer()))
.toList(); .toList();
var request = new ChatGPTRequestBuilder().contextRequest(context, content, systemMessage); var request = new ChatGPTRequestBuilder().contextRequest(context, content, systemMessage);
var response = this.chatGPTService.submit(request); var response = this.chatGPTService.submit(request);

View file

@ -1,59 +1,59 @@
package de.hhhammer.dchat.bot.openai; package de.hhhammer.dchat.bot.openai;
import de.hhhammer.dchat.bot.openai.MessageContext.PreviousInteraction;
import de.hhhammer.dchat.bot.openai.MessageContext.ReplyInteraction;
import de.hhhammer.dchat.bot.openai.models.ChatGPTRequest; import de.hhhammer.dchat.bot.openai.models.ChatGPTRequest;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ChatGPTRequestBuilder { public class ChatGPTRequestBuilder {
private static final String smallContextModel = "gpt-3.5-turbo"; private final String smallContextModel = "gpt-3.5-turbo";
private static final String bigContextModel = "gpt-3.5-turbo-16k"; private final String bigContextModel = "gpt-3.5-turbo-16k";
public ChatGPTRequestBuilder() { public ChatGPTRequestBuilder() {
} }
public ChatGPTRequest contextRequest(List<? extends MessageContext> contextMessages, String message, String systemMessage) { public ChatGPTRequest simpleRequest(String content, String systemMessage) {
List<ChatGPTRequest.Message> messages = getMessages(contextMessages, message, systemMessage);
String contextModel = contextMessages.size() <= 1 ? smallContextModel : bigContextModel;
return new ChatGPTRequest( return new ChatGPTRequest(
contextModel, smallContextModel,
List.of(new ChatGPTRequest.Message("system", systemMessage), new ChatGPTRequest.Message("user", content)),
0.7f
);
}
public ChatGPTRequest replyRequest(List<String> contextMessages, String message, String systemMessage) {
List<ChatGPTRequest.Message> messages = new ArrayList<>();
messages.add(new ChatGPTRequest.Message("system", systemMessage));
var context = contextMessages.stream()
.map(m -> new ChatGPTRequest.Message("assistant", m))
.toList();
messages.addAll(context);
messages.add(new ChatGPTRequest.Message("user", message));
return new ChatGPTRequest(
smallContextModel,
messages, messages,
0.7f 0.7f
); );
} }
@NotNull public ChatGPTRequest contextRequest(List<PreviousInteraction> contextMessages, String message, String systemMessage) {
private static List<ChatGPTRequest.Message> getMessages(List<? extends MessageContext> contextMessages, String message, String systemMessage) {
var systemMsg = new ChatGPTRequest.Message("system", systemMessage);
List<ChatGPTRequest.Message> contextMsgs = getContextMessages(contextMessages);
var userMessage = new ChatGPTRequest.Message("user", message);
List<ChatGPTRequest.Message> messages = new ArrayList<>(); List<ChatGPTRequest.Message> messages = new ArrayList<>();
messages.add(systemMsg); messages.add(new ChatGPTRequest.Message("system", systemMessage));
messages.addAll(contextMsgs); var context = contextMessages.stream()
messages.add(userMessage); .map(m -> List.of(
return messages; new ChatGPTRequest.Message("user", m.question),
} new ChatGPTRequest.Message("assistant", m.answer)
))
@NotNull
private static List<ChatGPTRequest.Message> getContextMessages(List<? extends MessageContext> contextMessages) {
return contextMessages.stream()
.map(ChatGPTRequestBuilder::mapContextMessages)
.flatMap(List::stream) .flatMap(List::stream)
.toList(); .toList();
messages.addAll(context);
messages.add(new ChatGPTRequest.Message("user", message));
return new ChatGPTRequest(
bigContextModel,
messages,
0.7f
);
} }
@NotNull public record PreviousInteraction(String question, String answer) {
private static List<ChatGPTRequest.Message> mapContextMessages(MessageContext contextMessage) {
return switch (contextMessage) {
case PreviousInteraction previousInteractions -> List.of(
new ChatGPTRequest.Message("user", previousInteractions.question()),
new ChatGPTRequest.Message("assistant", previousInteractions.answer())
);
case ReplyInteraction replyInteractions ->
List.of(new ChatGPTRequest.Message("assistant", replyInteractions.answer()));
};
} }
} }

View file

@ -13,14 +13,14 @@ import java.time.Duration;
public class ChatGPTService { public class ChatGPTService {
private static final String url = "https://api.openai.com/v1/chat/completions"; private static final String url = "https://api.openai.com/v1/chat/completions";
private final ObjectMapper mapper = new ObjectMapper();
private final String apiKey; private final String apiKey;
private final HttpClient httpClient; private final HttpClient httpClient;
private final ObjectMapper mapper;
public ChatGPTService(String apiKey, HttpClient httpClient, ObjectMapper mapper) {
public ChatGPTService(String apiKey, HttpClient httpClient) {
this.apiKey = apiKey; this.apiKey = apiKey;
this.httpClient = httpClient; this.httpClient = httpClient;
this.mapper = mapper;
} }
public ChatGPTResponse submit(ChatGPTRequest chatGPTRequest) throws IOException, InterruptedException, ResponseException { public ChatGPTResponse submit(ChatGPTRequest chatGPTRequest) throws IOException, InterruptedException, ResponseException {

View file

@ -1,9 +0,0 @@
package de.hhhammer.dchat.bot.openai;
public sealed interface MessageContext {
record ReplyInteraction(String answer) implements MessageContext {
}
record PreviousInteraction(String question, String answer) implements MessageContext {
}
}