Skip to content

Commit a8a761e

Browse files
committed
feature "rewrite-msg command": applies changes due to Wazei's first review - Part 1;
1 parent 5707f50 commit a8a761e

File tree

2 files changed

+89
-48
lines changed

2 files changed

+89
-48
lines changed

application/src/main/java/org/togetherjava/tjbot/features/Features.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.togetherjava.tjbot.features.mathcommands.wolframalpha.WolframAlphaCommand;
4242
import org.togetherjava.tjbot.features.mediaonly.MediaOnlyChannelListener;
4343
import org.togetherjava.tjbot.features.messages.MessageCommand;
44-
import org.togetherjava.tjbot.features.messages.RewriteMsgCommand;
44+
import org.togetherjava.tjbot.features.messages.RewriteCommand;
4545
import org.togetherjava.tjbot.features.moderation.BanCommand;
4646
import org.togetherjava.tjbot.features.moderation.KickCommand;
4747
import org.togetherjava.tjbot.features.moderation.ModerationActionsStore;
@@ -208,7 +208,7 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
208208
features.add(new ChatGptCommand(chatGptService, helpSystemHelper));
209209
features.add(new JShellCommand(jshellEval));
210210
features.add(new MessageCommand());
211-
features.add(new RewriteMsgCommand(chatGptService));
211+
features.add(new RewriteCommand(chatGptService));
212212

213213
FeatureBlacklist<Class<?>> blacklist = blacklistConfig.normal();
214214
return blacklist.filterStream(features.stream(), Object::getClass).toList();

application/src/main/java/org/togetherjava/tjbot/features/messages/RewriteMsgCommand.java renamed to application/src/main/java/org/togetherjava/tjbot/features/messages/RewriteCommand.java

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.togetherjava.tjbot.features.messages;
22

3+
import net.dv8tion.jda.api.entities.Message;
34
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
45
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
56
import net.dv8tion.jda.api.interactions.commands.OptionType;
@@ -19,55 +20,62 @@
1920

2021
/**
2122
* The implemented command is {@code /rewrite-msg}, which allows users to have their message
22-
* rewritten in a clearer, more professional, or better structured form using ChatGPT AI.
23+
* rewritten in a clearer, more professional, or better structured form using AI.
2324
* <p>
2425
* The rewritten message is shown as an ephemeral message visible only to the user who triggered the
25-
* command, making it perfect for getting quick writing improvements without cluttering the channel.
26+
* command.
2627
* <p>
27-
* Users can optionally specify a tone/style for the rewrite. If not provided, defaults to CLEAR.
28+
* Users can optionally specify a tone/style for the rewrite.
2829
*/
29-
public final class RewriteMsgCommand extends SlashCommandAdapter {
30-
private static final Logger logger = LoggerFactory.getLogger(RewriteMsgCommand.class);
31-
public static final String COMMAND_NAME = "rewrite-msg";
30+
public final class RewriteCommand extends SlashCommandAdapter {
31+
private static final Logger logger = LoggerFactory.getLogger(RewriteCommand.class);
32+
private static final String COMMAND_NAME = "rewrite";
3233
private static final String MESSAGE_OPTION = "message";
3334
private static final String TONE_OPTION = "tone";
34-
private static final int MAX_MESSAGE_LENGTH = 500;
35+
36+
private static final int MAX_MESSAGE_LENGTH = Message.MAX_CONTENT_LENGTH;
3537
private static final int MIN_MESSAGE_LENGTH = 3;
36-
private static final ChatGptModel CHAT_GPT_MODEL = ChatGptModel.HIGH_QUALITY;
38+
private static final ChatGptModel CHAT_GPT_MODEL = ChatGptModel.FASTEST;
3739

3840
private final ChatGptService chatGptService;
3941

40-
private static String buildResponse(String userMessage, String rewrittenMessage, MsgTone tone) {
41-
final String toneLabel = tone.displayName;
42-
42+
private static String createAiPrompt(String userMessage, MessageTone tone) {
4343
return """
44-
**Rewritten message (%s)**
44+
Rewrite the following message to make it clearer, more professional, \
45+
and better structured. Maintain the original meaning while improving the quality \
46+
of the writing. Do NOT use em-dashes (—). %s
4547
46-
**Original:**
47-
%s
48+
IMPORTANT: The rewritten text MUST be no more than 2000 characters. \
49+
If needed, compress wording while preserving key details and intent.
50+
51+
If the message is already well-written, provide minor improvements.
4852
49-
**Rewritten:**
50-
%s""".formatted(toneLabel, userMessage, rewrittenMessage);
53+
Original message:
54+
%s""".stripIndent().formatted(tone.description, userMessage);
5155
}
5256

53-
private static String buildChatGptPrompt(String userMessage, MsgTone tone) {
57+
private static String buildOriginalMsgResponse(String userMessage, MessageTone tone) {
5458
return """
55-
Please rewrite the following message to make it clearer, more professional, \
56-
and better structured. Maintain the original meaning while improving the quality \
57-
of the writing. Do NOT use em-dashes (—). %s
59+
**Original message (%s)**
5860
59-
If the message is already well-written, provide minor improvements.
61+
%s
62+
""".stripIndent().formatted(tone.displayName, userMessage);
63+
}
6064

61-
Original message:
62-
%s""".formatted(tone.description, userMessage);
65+
private static String buildRewrittenMsgResponse(String aiMessage, MessageTone tone) {
66+
return """
67+
**Rewritten message (%s)**
68+
69+
%s
70+
""".stripIndent().formatted(tone.displayName, aiMessage);
6371
}
6472

6573
/**
6674
* Creates the slash command definition and configures available options for rewriting messages.
6775
*
6876
* @param chatGptService service for interacting with ChatGPT
6977
*/
70-
public RewriteMsgCommand(ChatGptService chatGptService) {
78+
public RewriteCommand(ChatGptService chatGptService) {
7179
super(COMMAND_NAME, "Let AI rephrase and improve your message", CommandVisibility.GUILD);
7280

7381
this.chatGptService = chatGptService;
@@ -79,64 +87,97 @@ public RewriteMsgCommand(ChatGptService chatGptService) {
7987
.setMaxLength(MAX_MESSAGE_LENGTH);
8088

8189
final OptionData toneOption = new OptionData(OptionType.STRING, TONE_OPTION,
82-
"The tone/style for the rewritten message (default: " + MsgTone.CLEAR.displayName
83-
+ ")",
90+
"The tone/style for the rewritten message (default: "
91+
+ MessageTone.CLEAR.displayName + ")",
8492
false);
8593

86-
Arrays.stream(MsgTone.values())
94+
Arrays.stream(MessageTone.values())
8795
.forEach(tone -> toneOption.addChoice(tone.displayName, tone.name()));
8896

8997
getData().addOptions(messageOption, toneOption);
9098
}
9199

92100
@Override
93101
public void onSlashCommand(SlashCommandInteractionEvent event) {
102+
94103
final String userMessage =
95104
Objects.requireNonNull(event.getOption(MESSAGE_OPTION)).getAsString();
96-
97-
final MsgTone tone = parseTone(event.getOption(TONE_OPTION), event.getUser().getId());
105+
final MessageTone tone = parseTone(event.getOption(TONE_OPTION));
98106

99107
event.deferReply(true).queue();
100108

101-
final Optional<String> rewrittenMessage = this.rewrite(userMessage, tone);
109+
Optional<String> rewrittenMessage = rewrite(userMessage, tone);
102110

103111
if (rewrittenMessage.isEmpty()) {
104-
logger.debug("Failed to obtain a response for /rewrite-msg, original message: '{}'",
105-
userMessage);
112+
logger.debug("Failed to obtain a response for /{}, original message: '{}'",
113+
COMMAND_NAME, userMessage);
114+
106115
event.getHook()
107116
.editOriginal(
108117
"An error occurred while processing your request. Please try again later.")
109118
.queue();
119+
110120
return;
111121
}
112122

113-
final String response = buildResponse(userMessage, rewrittenMessage.orElseThrow(), tone);
123+
final String rewrittenText = rewrittenMessage.orElseThrow();
114124

115-
event.getHook().editOriginal(response).queue();
125+
logger.debug("Rewrite successful; rewritten message length: {}", rewrittenText.length());
126+
127+
event.getHook()
128+
.sendMessage(buildOriginalMsgResponse(userMessage, tone))
129+
.setEphemeral(true)
130+
.queue();
131+
132+
event.getHook()
133+
.sendMessage(buildRewrittenMsgResponse(rewrittenText, tone))
134+
.setEphemeral(true)
135+
.queue();
116136
}
117137

118-
private MsgTone parseTone(@Nullable OptionMapping toneOption, String userId)
138+
private MessageTone parseTone(@Nullable OptionMapping toneOption)
119139
throws IllegalArgumentException {
140+
120141
if (toneOption == null) {
121-
logger.debug("Tone option not provided for user: {}, using default CLEAR", userId);
122-
return MsgTone.CLEAR;
142+
logger.debug("Tone option not provided, using default '{}'", MessageTone.CLEAR.name());
143+
return MessageTone.CLEAR;
123144
}
124145

125146
final String toneValue = toneOption.getAsString();
126-
final MsgTone tone = MsgTone.valueOf(toneValue);
127-
128-
logger.debug("Parsed tone '{}' for user: {}", tone.displayName, userId);
129147

130-
return tone;
148+
return MessageTone.valueOf(toneValue);
131149
}
132150

133-
private Optional<String> rewrite(String userMessage, MsgTone tone) {
134-
final String rewritePrompt = buildChatGptPrompt(userMessage, tone);
151+
private Optional<String> rewrite(String userMessage, MessageTone tone) {
152+
153+
final String rewritePrompt = createAiPrompt(userMessage, tone);
154+
155+
Optional<String> attempt =
156+
chatGptService.ask(rewritePrompt, tone.displayName, CHAT_GPT_MODEL);
157+
158+
if (attempt.isEmpty()) {
159+
return attempt;
160+
}
161+
162+
final String response = attempt.get();
163+
164+
if (response.length() <= Message.MAX_CONTENT_LENGTH) {
165+
return attempt;
166+
}
167+
168+
logger.debug("Rewritten message exceeded {} characters; retrying with stricter constraint",
169+
Message.MAX_CONTENT_LENGTH);
170+
171+
final String shortenPrompt = rewritePrompt
172+
+ "\n\nConstraint reminder: Your previous rewrite exceeded "
173+
+ Message.MAX_CONTENT_LENGTH
174+
+ " characters. Provide a revised rewrite strictly under "
175+
+ Message.MAX_CONTENT_LENGTH + " characters while preserving meaning and tone.";
135176

136-
return chatGptService.ask(rewritePrompt, tone.displayName, CHAT_GPT_MODEL);
177+
return chatGptService.ask(shortenPrompt, tone.displayName, CHAT_GPT_MODEL);
137178
}
138179

139-
private enum MsgTone {
180+
private enum MessageTone {
140181
CLEAR("Clear", "Make it clear and easy to understand."),
141182
PRO("Pro", "Use a professional and polished tone."),
142183
DETAILED("Detailed", "Expand with more detail and explanation."),
@@ -145,7 +186,7 @@ private enum MsgTone {
145186
private final String displayName;
146187
private final String description;
147188

148-
MsgTone(String displayName, String description) {
189+
MessageTone(String displayName, String description) {
149190
this.displayName = displayName;
150191
this.description = description;
151192
}

0 commit comments

Comments
 (0)