diff --git a/.env b/.env new file mode 100644 index 0000000..d249bd5 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +export SIREN_VERSION=0.1.14 \ No newline at end of file diff --git a/Makefile b/Makefile index f017364..ce6fe43 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ SHELL := /bin/bash +include .env build: docker rmi siren && docker-compose build @@ -18,3 +19,11 @@ exec: clean: docker rmi siren + +deploy: + @echo "Deploying application..." + @mvn clean deploy || { \ + echo "Deployment failed!"; \ + exit 1; \ + } + @echo "Deployment successful!" diff --git a/docker-compose.yml b/docker-compose.yml index 41a9afc..138ff0e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: dockerfile: ./Dockerfile args: - JAVA_VERSION=17 - - VERSION=0.1.13 + - VERSION=${SIREN_VERSION} volumes: - ./data:/app restart: unless-stopped diff --git a/pom.xml b/pom.xml index 470adad..d86395b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.bensherriff siren - 0.1.13 + ${env.SIREN_VERSION} jar diff --git a/src/main/java/com/bensherriff/siren/openai/OpenAIManager.java b/src/main/java/com/bensherriff/siren/openai/OpenAIManager.java index 19cc1cd..28a2b78 100644 --- a/src/main/java/com/bensherriff/siren/openai/OpenAIManager.java +++ b/src/main/java/com/bensherriff/siren/openai/OpenAIManager.java @@ -27,12 +27,13 @@ public class OpenAIManager { private final Settings settings; private final JDA jda; private final ScheduledExecutorService executor; - private final Map> threadMessages = new HashMap<>(); + private final Map> threadMessages; public OpenAIManager(Listener listener) { this.settings = listener.getSettings(); this.jda = listener.getJDA(); this.executor = listener.getExecutor(); + this.threadMessages = new HashMap<>(); if (settings.getOpenAISettings().getToken().isEmpty()) { LOGGER.warn("No OpenAI token; OpenAI functionality is disabled"); @@ -48,106 +49,106 @@ public class OpenAIManager { * @param event The message event received */ public void handleEvent(MessageReceivedEvent event) { - String message = parseMessage(event.getMessage().getContentRaw()); - long guildId = event.getGuild().getIdLong(); - GuildSettings guildSettings = settings.getGuildSettings().get(guildId); - Model model = settings.getGuildSettings().get(guildId).getModel(); - - if (event.getAuthor().isBot()) { - return; - } - - if (message.isEmpty() || message.isBlank()) { - event.getMessage().reply("Your message is empty. Please try again").queue(); - } - if (shouldReply(event)) { if (openAiService != null) { - LOGGER.trace("Guild: <{}> User: <{}> Message: <{}>", guildId, event.getAuthor().getId(), message); - executor.execute(() -> { - try { - StringBuilder stringBuilder = new StringBuilder(); - List chatMessages = new ArrayList<>(); - ChatMessage chatMessage = createChatMessage(message, event); - - // Send OpenAI Message and get response - switch (model) { - case DAVINCI_3, DAVINCI_2, CURIE_1, BABBAGE_1, ADA_1 -> { - CompletionRequest completionRequest = CompletionRequest.builder() - .model(guildSettings.getModel().getName()) - .maxTokens(guildSettings.getMaxTokens()) - .user(event.getAuthor().getId()) - .temperature(settings.getOpenAISettings().getTemperature()) - .topP(settings.getOpenAISettings().getTopP()) - .frequencyPenalty(settings.getOpenAISettings().getFrequencyPenalty()) - .presencePenalty(settings.getOpenAISettings().getPresencePenalty()) - .prompt(message) - .build(); - CompletionResult completionResult = openAiService.createCompletion(completionRequest); - completionResult.getChoices().forEach(choice -> stringBuilder.append(choice.getText().trim())); - } - case GPT_4, GPT_4_0314, GPT_4_32K, GPT_4_32K_0314, GPT_35_TURBO, GPT_35_TURBO_0301 -> { - - //TODO check logic here, something is broken -// if (event.isFromThread()) { -// String channelId = event.getChannel().asThreadChannel().getId(); -// // Update ThreadMessages with the new message, and add previous messages to be sent out -// if (threadMessages.containsKey(channelId)) { -// chatMessages.addAll(threadMessages.get(channelId)); -// threadMessages.get(channelId).add(chatMessage); -// } else { -// threadMessages.put(channelId, List.of(chatMessage)); -// } -// } - chatMessages.add(chatMessage); - - ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder() - .model(guildSettings.getModel().getName()) - .maxTokens(guildSettings.getMaxTokens()) - .user(event.getAuthor().getId()) - .temperature(settings.getOpenAISettings().getTemperature()) - .topP(settings.getOpenAISettings().getTopP()) - .frequencyPenalty(settings.getOpenAISettings().getFrequencyPenalty()) - .presencePenalty(settings.getOpenAISettings().getPresencePenalty()) - .messages(chatMessages) - .build(); - ChatCompletionResult chatCompletionResult = openAiService.createChatCompletion(chatCompletionRequest); - chatCompletionResult.getChoices().forEach(choice -> stringBuilder.append(choice.getMessage().getContent().trim())); - } - default -> { - event.getMessage().reply("Unexpected model in settings. Please contact an administrator.").queue(); - LOGGER.warn("Unexpected model in settings for guild {}: {}. Expected one of {}", guildId, - model, Arrays.toString(Model.values())); - return; - } - } - - // Respond to user - if (event.isFromThread()) { - ThreadChannel channel = event.getChannel().asThreadChannel(); - channel.sendMessage(stringBuilder.toString()).queue(); - } else { - String threadTitle = message; - if (message.length() > 20) { - threadTitle = message.substring(0, 20); - } - event.getMessage().createThreadChannel(threadTitle).queue(channel -> { - channel.sendMessage(stringBuilder.toString()).queue(); - threadMessages.put(channel.getId(), List.of(chatMessage)); - }); - } - - } catch (Exception ex) { - LOGGER.error(ex.getMessage()); - event.getMessage().reply("An error occurred while processing your message. Please contact your administrator.").queue(); - } - }); + executor.execute(() -> sendMessage(event)); } else { event.getMessage().reply("OpenAI functionality is disabled. Please contact an administrator").queue(); } } } + private void sendMessage(MessageReceivedEvent event) { + String message = parseMessage(event.getMessage().getContentRaw()); + long guildId = event.getGuild().getIdLong(); + Model model = settings.getGuildSettings().get(guildId).getModel(); + GuildSettings guildSettings = settings.getGuildSettings().get(guildId); + + LOGGER.trace("Guild: <{}> User: <{}> Message: <{}>", guildId, event.getAuthor().getId(), message); + + if (message.isEmpty() || message.isBlank()) { + event.getMessage().reply("Your message is empty. Please try again").queue(); + return; + } + + StringBuilder stringBuilder = new StringBuilder(); + List chatMessages = new ArrayList<>(); + ChatMessage chatMessage = createChatMessage(message, event); + + try { + // Send OpenAI Message and get response + switch (model) { + case DAVINCI_3, DAVINCI_2, CURIE_1, BABBAGE_1, ADA_1 -> { + CompletionRequest completionRequest = CompletionRequest.builder() + .model(guildSettings.getModel().getName()) + .maxTokens(guildSettings.getMaxTokens()) + .user(event.getAuthor().getId()) + .temperature(settings.getOpenAISettings().getTemperature()) + .topP(settings.getOpenAISettings().getTopP()) + .frequencyPenalty(settings.getOpenAISettings().getFrequencyPenalty()) + .presencePenalty(settings.getOpenAISettings().getPresencePenalty()) + .prompt(message) + .build(); + CompletionResult completionResult = openAiService.createCompletion(completionRequest); + completionResult.getChoices().forEach(choice -> stringBuilder.append(choice.getText().trim())); + } + case GPT_4, GPT_4_0314, GPT_4_32K, GPT_4_32K_0314, GPT_35_TURBO, GPT_35_TURBO_0301 -> { + //TODO Handle memories properly +// if (event.isFromThread()) { +// String channelId = event.getChannel().asThreadChannel().getId(); +// // Update ThreadMessages with the new message, and add previous messages to be sent out +// if (threadMessages.containsKey(channelId)) { +// threadMessages.get(channelId).add(chatMessage); +// chatMessages.addAll(threadMessages.get(channelId)); +// } else { +// threadMessages.put(channelId, new ArrayList<>(Arrays.asList(chatMessage))); +// } +// } + chatMessages.add(chatMessage); + + ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder() + .model(guildSettings.getModel().getName()) + .maxTokens(guildSettings.getMaxTokens()) + .user(event.getAuthor().getId()) + .temperature(settings.getOpenAISettings().getTemperature()) + .topP(settings.getOpenAISettings().getTopP()) + .frequencyPenalty(settings.getOpenAISettings().getFrequencyPenalty()) + .presencePenalty(settings.getOpenAISettings().getPresencePenalty()) + .messages(chatMessages) + .build(); + ChatCompletionResult chatCompletionResult = openAiService.createChatCompletion(chatCompletionRequest); + chatCompletionResult.getChoices().forEach(choice -> stringBuilder.append(choice.getMessage().getContent().trim())); + } + default -> { + event.getMessage().reply("Unexpected model in settings. Please contact an administrator.").queue(); + LOGGER.warn("Unexpected model in settings for guild {}: {}. Expected one of {}", guildId, + model, Arrays.toString(Model.values())); + return; + } + } + + // Respond to user + if (event.isFromThread()) { + ThreadChannel channel = event.getChannel().asThreadChannel(); + channel.sendMessage(stringBuilder.toString()).queue(); + } else { + // The max discord title length is 100 characters + String threadTitle = message; + if (message.length() > 100) { + threadTitle = message.substring(0, 100); + } + event.getMessage().createThreadChannel(threadTitle).queue(channel -> { + channel.sendMessage(stringBuilder.toString()).queue(); +// threadMessages.put(channel.getId(), new ArrayList<>(Arrays.asList(chatMessage))); + }); + } + + } catch (Exception ex) { + LOGGER.error("Caught exception while processing message; {}", ex.getMessage()); + event.getMessage().reply("An error occurred while processing your message. Please contact your administrator.").queue(); + } + } + private ChatMessage createChatMessage(String message, MessageReceivedEvent event) { ChatMessage chatMessage = new ChatMessage(); chatMessage.setContent(message); @@ -185,7 +186,7 @@ public class OpenAIManager { } } } catch (Exception ex) { - LOGGER.error(ex.getMessage()); + LOGGER.error("Failed to determine bot reply status; {}", ex.getMessage()); return false; } return shouldReply;