From fe1cae95c53f1e90f56530865a3283ecdd691eb6 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 8 Jan 2026 11:17:59 +0000 Subject: [PATCH 1/5] Update ChatGPT model to GPT_5_MINI --- .../org/togetherjava/tjbot/features/chatgpt/ChatGptService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java index f5790af185..70f5061fb6 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java @@ -76,7 +76,7 @@ public Optional ask(String question, @Nullable String context) { String response = null; try { ResponseCreateParams params = ResponseCreateParams.builder() - .model(ChatModel.GPT_5_NANO) + .model(ChatModel.GPT_5_MINI) .input(inputPrompt) .maxOutputTokens(MAX_TOKENS) .build(); From 10cc87f488623df03caa982c945ac5fff056abc6 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 8 Jan 2026 11:35:07 +0000 Subject: [PATCH 2/5] feat: add a chat model parameter to allow choice between models (speed vs quality) --- .../togetherjava/tjbot/features/chatgpt/ChatGptCommand.java | 5 +++-- .../togetherjava/tjbot/features/chatgpt/ChatGptService.java | 5 +++-- .../togetherjava/tjbot/features/help/HelpSystemHelper.java | 3 ++- .../tjbot/features/moderation/TransferQuestionCommand.java | 4 +++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java index 163220d8a5..f0e1c86a71 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java @@ -2,6 +2,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; +import com.openai.models.ChatModel; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.SelfUser; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; @@ -82,8 +83,8 @@ public void onModalSubmitted(ModalInteractionEvent event, List args) { String question = event.getValue(QUESTION_INPUT).getAsString(); - Optional chatgptResponse = - chatGptService.ask(question, "You may use markdown syntax for the response"); + Optional chatgptResponse = chatGptService.ask(question, + "You may use markdown syntax for the response", ChatModel.GPT_5_MINI); if (chatgptResponse.isPresent()) { userIdToAskedAtCache.put(event.getMember().getId(), Instant.now()); } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java index 70f5061fb6..f1cb177394 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java @@ -51,11 +51,12 @@ public ChatGptService(Config config) { * @param question The question being asked of ChatGPT. Max is {@value MAX_TOKENS} tokens. * @param context The category of asked question, to set the context(eg. Java, Database, Other * etc). + * @param chatModel The AI model to use for this request. * @return response from ChatGPT as a String. * @see ChatGPT * Tokens. */ - public Optional ask(String question, @Nullable String context) { + public Optional ask(String question, @Nullable String context, ChatModel chatModel) { if (isDisabled) { return Optional.empty(); } @@ -76,7 +77,7 @@ public Optional ask(String question, @Nullable String context) { String response = null; try { ResponseCreateParams params = ResponseCreateParams.builder() - .model(ChatModel.GPT_5_MINI) + .model(chatModel) .input(inputPrompt) .maxOutputTokens(MAX_TOKENS) .build(); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java index dbb6ed55e2..d8e8093df3 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java @@ -1,5 +1,6 @@ package org.togetherjava.tjbot.features.help; +import com.openai.models.ChatModel; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; @@ -143,7 +144,7 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, String context = "Category %s on a Java Q&A discord server. You may use markdown syntax for the response" .formatted(matchingTag.getName()); - chatGptAnswer = chatGptService.ask(question, context); + chatGptAnswer = chatGptService.ask(question, context, ChatModel.GPT_3_5_TURBO); if (chatGptAnswer.isEmpty()) { return useChatGptFallbackMessage(threadChannel); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java index 9751397137..79eb927a2c 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java @@ -1,5 +1,6 @@ package org.togetherjava.tjbot.features.moderation; +import com.openai.models.ChatModel; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; @@ -98,7 +99,8 @@ public void onMessageContext(MessageContextInteractionEvent event) { String chatGptTitleRequest = "Summarize the following question into a concise title or heading not more than 5 words, remove quotations if any: %s" .formatted(originalMessage); - Optional chatGptTitle = chatGptService.ask(chatGptTitleRequest, null); + Optional chatGptTitle = + chatGptService.ask(chatGptTitleRequest, null, ChatModel.GPT_3_5_TURBO); String title = chatGptTitle.orElse(createTitle(originalMessage)); if (title.startsWith("\"") && title.endsWith("\"")) { title = title.substring(1, title.length() - 1); From 0763cbeaaf8b9b7e72373da4a37c8775b5a167fb Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 8 Jan 2026 17:06:50 +0000 Subject: [PATCH 3/5] feat: create an enum to house the AI models --- .../features/chatgpt/ChatGptCommand.java | 3 +- .../tjbot/features/chatgpt/ChatGptModel.java | 42 +++++++++++++++++++ .../features/chatgpt/ChatGptService.java | 5 +-- .../tjbot/features/help/HelpSystemHelper.java | 4 +- .../moderation/TransferQuestionCommand.java | 4 +- 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java index f0e1c86a71..a91633688d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java @@ -2,7 +2,6 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import com.openai.models.ChatModel; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.SelfUser; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; @@ -84,7 +83,7 @@ public void onModalSubmitted(ModalInteractionEvent event, List args) { String question = event.getValue(QUESTION_INPUT).getAsString(); Optional chatgptResponse = chatGptService.ask(question, - "You may use markdown syntax for the response", ChatModel.GPT_5_MINI); + "You may use markdown syntax for the response", ChatGptModel.HIGH_QUALITY); if (chatgptResponse.isPresent()) { userIdToAskedAtCache.put(event.getMember().getId(), Instant.now()); } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java new file mode 100644 index 0000000000..ef561e44ca --- /dev/null +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java @@ -0,0 +1,42 @@ +package org.togetherjava.tjbot.features.chatgpt; + +import com.openai.models.ChatModel; + +/** + * Logical abstraction over OpenAI chat models. + *

+ * This enum allows the application to select models based on performance/quality intent rather than + * hard-coding specific OpenAI model versions throughout the codebase. + * + */ +public enum ChatGptModel { + /** + * Fastest response time with the lowest computational cost. + */ + FASTEST(ChatModel.GPT_3_5_TURBO), + + /** + * Balanced option between speed and quality. + */ + FAST(ChatModel.GPT_4_1_MINI), + + /** + * Highest quality responses with increased reasoning capability. + */ + HIGH_QUALITY(ChatModel.GPT_5_MINI); + + private final ChatModel chatModel; + + ChatGptModel(ChatModel chatModel) { + this.chatModel = chatModel; + } + + public ChatModel toChatModel() { + return chatModel; + } + + @Override + public String toString() { + return chatModel.toString(); + } +} diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java index f1cb177394..02e32cde6e 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptService.java @@ -2,7 +2,6 @@ import com.openai.client.OpenAIClient; import com.openai.client.okhttp.OpenAIOkHttpClient; -import com.openai.models.ChatModel; import com.openai.models.responses.Response; import com.openai.models.responses.ResponseCreateParams; import com.openai.models.responses.ResponseOutputText; @@ -56,7 +55,7 @@ public ChatGptService(Config config) { * @see ChatGPT * Tokens. */ - public Optional ask(String question, @Nullable String context, ChatModel chatModel) { + public Optional ask(String question, @Nullable String context, ChatGptModel chatModel) { if (isDisabled) { return Optional.empty(); } @@ -77,7 +76,7 @@ public Optional ask(String question, @Nullable String context, ChatModel String response = null; try { ResponseCreateParams params = ResponseCreateParams.builder() - .model(chatModel) + .model(chatModel.toChatModel()) .input(inputPrompt) .maxOutputTokens(MAX_TOKENS) .build(); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java index d8e8093df3..ab1309b0ac 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.features.help; -import com.openai.models.ChatModel; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; @@ -26,6 +25,7 @@ import org.togetherjava.tjbot.db.generated.tables.HelpThreads; import org.togetherjava.tjbot.db.generated.tables.records.HelpThreadsRecord; import org.togetherjava.tjbot.features.chatgpt.ChatGptCommand; +import org.togetherjava.tjbot.features.chatgpt.ChatGptModel; import org.togetherjava.tjbot.features.chatgpt.ChatGptService; import org.togetherjava.tjbot.features.componentids.ComponentIdInteractor; import org.togetherjava.tjbot.features.utils.Guilds; @@ -144,7 +144,7 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, String context = "Category %s on a Java Q&A discord server. You may use markdown syntax for the response" .formatted(matchingTag.getName()); - chatGptAnswer = chatGptService.ask(question, context, ChatModel.GPT_3_5_TURBO); + chatGptAnswer = chatGptService.ask(question, context, ChatGptModel.FAST); if (chatGptAnswer.isEmpty()) { return useChatGptFallbackMessage(threadChannel); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java index 79eb927a2c..8fe47ce1f4 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/moderation/TransferQuestionCommand.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.features.moderation; -import com.openai.models.ChatModel; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; @@ -32,6 +31,7 @@ import org.togetherjava.tjbot.features.BotCommandAdapter; import org.togetherjava.tjbot.features.CommandVisibility; import org.togetherjava.tjbot.features.MessageContextCommand; +import org.togetherjava.tjbot.features.chatgpt.ChatGptModel; import org.togetherjava.tjbot.features.chatgpt.ChatGptService; import org.togetherjava.tjbot.features.utils.StringDistances; @@ -100,7 +100,7 @@ public void onMessageContext(MessageContextInteractionEvent event) { "Summarize the following question into a concise title or heading not more than 5 words, remove quotations if any: %s" .formatted(originalMessage); Optional chatGptTitle = - chatGptService.ask(chatGptTitleRequest, null, ChatModel.GPT_3_5_TURBO); + chatGptService.ask(chatGptTitleRequest, null, ChatGptModel.FASTEST); String title = chatGptTitle.orElse(createTitle(originalMessage)); if (title.startsWith("\"") && title.endsWith("\"")) { title = title.substring(1, title.length() - 1); From 2dfbb0fbb6c6b3354378143518be88fdd8ace766 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 8 Jan 2026 17:13:30 +0000 Subject: [PATCH 4/5] update AI response footer to include model --- .../tjbot/features/chatgpt/ChatGptCommand.java | 6 ++++-- .../tjbot/features/help/HelpSystemHelper.java | 11 +++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java index a91633688d..1f9b3208fb 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptCommand.java @@ -25,6 +25,7 @@ * which it will respond with an AI generated answer. */ public final class ChatGptCommand extends SlashCommandAdapter { + private static final ChatGptModel CHAT_GPT_MODEL = ChatGptModel.HIGH_QUALITY; public static final String COMMAND_NAME = "chatgpt"; private static final String QUESTION_INPUT = "question"; private static final int MAX_MESSAGE_INPUT_LENGTH = 200; @@ -83,7 +84,7 @@ public void onModalSubmitted(ModalInteractionEvent event, List args) { String question = event.getValue(QUESTION_INPUT).getAsString(); Optional chatgptResponse = chatGptService.ask(question, - "You may use markdown syntax for the response", ChatGptModel.HIGH_QUALITY); + "You may use markdown syntax for the response", CHAT_GPT_MODEL); if (chatgptResponse.isPresent()) { userIdToAskedAtCache.put(event.getMember().getId(), Instant.now()); } @@ -96,7 +97,8 @@ public void onModalSubmitted(ModalInteractionEvent event, List args) { String response = chatgptResponse.orElse(errorResponse); SelfUser selfUser = event.getJDA().getSelfUser(); - MessageEmbed responseEmbed = helper.generateGptResponseEmbed(response, selfUser, question); + MessageEmbed responseEmbed = + helper.generateGptResponseEmbed(response, selfUser, question, CHAT_GPT_MODEL); event.getHook().sendMessageEmbeds(responseEmbed).queue(); } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java index ab1309b0ac..477434b306 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java @@ -56,6 +56,7 @@ */ public final class HelpSystemHelper { private static final Logger logger = LoggerFactory.getLogger(HelpSystemHelper.class); + private static final ChatGptModel CHAT_GPT_MODEL = ChatGptModel.FAST; static final Color AMBIENT_COLOR = new Color(255, 255, 165); @@ -144,7 +145,7 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, String context = "Category %s on a Java Q&A discord server. You may use markdown syntax for the response" .formatted(matchingTag.getName()); - chatGptAnswer = chatGptService.ask(question, context, ChatGptModel.FAST); + chatGptAnswer = chatGptService.ask(question, context, CHAT_GPT_MODEL); if (chatGptAnswer.isEmpty()) { return useChatGptFallbackMessage(threadChannel); @@ -169,7 +170,8 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, answer = answer.substring(0, responseCharLimit); } - MessageEmbed responseEmbed = generateGptResponseEmbed(answer, selfUser, originalQuestion); + MessageEmbed responseEmbed = + generateGptResponseEmbed(answer, selfUser, originalQuestion, CHAT_GPT_MODEL); return post.flatMap(_ -> threadChannel.sendMessageEmbeds(responseEmbed) .addActionRow(generateDismissButton(componentIdInteractor, messageId.get()))); } @@ -182,8 +184,9 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, * @param title The title for the MessageEmbed. * @return A MessageEmbed that contains response generated by AI. */ - public MessageEmbed generateGptResponseEmbed(String answer, SelfUser selfUser, String title) { - String responseByGptFooter = "- AI generated response"; + public MessageEmbed generateGptResponseEmbed(String answer, SelfUser selfUser, String title, + ChatGptModel model) { + String responseByGptFooter = "- AI generated response using %s model".formatted(model); int embedTitleLimit = MessageEmbed.TITLE_MAX_LENGTH; String capitalizedTitle = Character.toUpperCase(title.charAt(0)) + title.substring(1); From 3c086d3fbbe56997fd35eb9081ec1b1f5d173b82 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 8 Jan 2026 17:18:48 +0000 Subject: [PATCH 5/5] docs: add java docs --- .../org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java | 3 +++ .../org/togetherjava/tjbot/features/help/HelpSystemHelper.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java index ef561e44ca..e08951f4b3 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/chatgpt/ChatGptModel.java @@ -31,6 +31,9 @@ public enum ChatGptModel { this.chatModel = chatModel; } + /** + * @return the underlying OpenAI model used by this enum. + */ public ChatModel toChatModel() { return chatModel; } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java index 477434b306..edf217f1ea 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpSystemHelper.java @@ -181,7 +181,8 @@ RestAction constructChatGptAttempt(ThreadChannel threadChannel, * * @param answer The response text generated by AI. * @param selfUser The SelfUser representing the bot. - * @param title The title for the MessageEmbed. + * @param title The title for the MessageEmbed + * @param model The AI model that was used for the foot notes * @return A MessageEmbed that contains response generated by AI. */ public MessageEmbed generateGptResponseEmbed(String answer, SelfUser selfUser, String title,