Skip to content

Commit

Permalink
Use moderation endpoint for all messages
Browse files Browse the repository at this point in the history
  • Loading branch information
xdnw committed May 12, 2024
1 parent c740666 commit 9aee4a2
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 34 deletions.
7 changes: 1 addition & 6 deletions src/main/java/link/locutus/discord/commands/account/Say.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ public String onCommand(Guild guild, IMessageIO channel, User author, DBNation m
msg = msg.replace("@", "@\u200B");
msg = msg.replace("&", "&\u200B");

PWGPTHandler gpt = Locutus.imp().getCommandManager().getV2().getPwgptHandler();
if (gpt != null) {
GptHandler handler = gpt.getHandler();
List<ModerationResult> result = handler.getModerator().moderate(msg);
GPTUtil.checkThrowModeration(result, "<redacted>");
}
GPTUtil.checkThrowModeration(msg);
NationPlaceholders formatter = Locutus.imp().getCommandManager().getV2().getNationPlaceholders();
return formatter.format2(guild, me, author, msg.substring(5) + "\n\n- " + author.getAsMention(), me, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import link.locutus.discord.config.Settings;
import link.locutus.discord.db.GuildDB;
import link.locutus.discord.db.entities.DBNation;
import link.locutus.discord.gpt.GPTUtil;
import link.locutus.discord.user.Roles;
import link.locutus.discord.util.MarkupUtil;
import link.locutus.discord.util.discord.DiscordUtil;
Expand Down Expand Up @@ -75,6 +76,7 @@ public String onCommand(Guild guild, IMessageIO channel, User author, DBNation m
String content = DiscordUtil.trimContent(fullCommandRaw);
String body = content.substring(content.indexOf(' ', content.indexOf("message/id=")) + 1);

GPTUtil.checkThrowModeration(body);
String result = new MailRespondTask(auth, arg0, messageId, body, null).call();
return "Mail: " + result;
}
Expand Down Expand Up @@ -131,6 +133,7 @@ public String onCommand(Guild guild, IMessageIO channel, User author, DBNation m
if (!Roles.ADMIN.hasOnRoot(author)) {
message += "\n\n<i>This message was sent by: " + author.getName() + "</i>";
}
GPTUtil.checkThrowModeration(message);

CompletableFuture<IMessageBuilder> msgFuture = channel.sendMessage("Sending to...");
IMessageBuilder msg = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package link.locutus.discord.commands.manager.v2.impl.pw.commands;

import link.locutus.discord.gpt.GPTUtil;
import link.locutus.wiki.WikiGenHandler;
import link.locutus.discord.Locutus;
import link.locutus.discord.RequestTracker;
Expand Down Expand Up @@ -1093,7 +1094,7 @@ public String mask(@Me Member me, @Me GuildDB db, Set<Member> members, Role role
public String dm(@Me User author, DBNation nation, String message) {
User user = nation.getUser();
if (user == null) return "No user found for " + nation.getNation();

GPTUtil.checkThrowModeration(message);
user.openPrivateChannel().queue(new Consumer<PrivateChannel>() {
@Override
public void accept(PrivateChannel channel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,7 @@ public String say(NationPlaceholders placeholders, ValueStore store, @Me GuildDB
msg = msg.replace("@", "@\u200B");
msg = msg.replace("&", "&\u200B");

PWGPTHandler gpt = Locutus.imp().getCommandManager().getV2().getPwgptHandler();
if (gpt != null) {
GptHandler handler = gpt.getHandler();
List<ModerationResult> result = handler.getModerator().moderate(msg);
GPTUtil.checkThrowModeration(result, "<redacted>");
}
GPTUtil.checkThrowModeration(msg);

msg = msg + "\n\n- " + author.getAsMention();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import link.locutus.discord.db.entities.DBAlliance;
import link.locutus.discord.db.guild.GuildKey;
import link.locutus.discord.db.guild.SheetKey;
import link.locutus.discord.gpt.GPTUtil;
import link.locutus.discord.pnw.AllianceList;
import link.locutus.discord.pnw.NationList;
import link.locutus.discord.pnw.PNWUser;
Expand Down Expand Up @@ -396,7 +397,6 @@ public static IMessageBuilder sortChannels(@Me GuildDB db, @Me Guild guild, @Me
} else {
changes.add(channel.getAsMention() + ": " + currCategory.getAsMention() + " -> " + nonMax.getName());
}

}
}
nationChannels.entrySet().stream().filter(f -> f.getValue().size() > 1).forEach(f -> errors.putIfAbsent(f.getValue().iterator().next(), "Nation has multiple channels"));
Expand Down Expand Up @@ -1185,6 +1185,7 @@ public String incentiveRanking(@Me GuildDB db, @Me IMessageIO io, @Me JSONObject
public String reply(@Me GuildDB db, @Me DBNation me, @Me User author, @Me IMessageIO channel, @Arg("The nation you are replying to") DBNation receiver, @Arg("The url of the mail") String url, String message, @Arg("The account to reply with\nMust be the same account that received the mail") @Switch("s") DBNation sender) throws IOException {
if (!url.contains("message/id=")) return "URL must be a message url";
int messageId = Integer.parseInt(url.split("=")[1]);
GPTUtil.checkThrowModeration(message);

Auth auth;
if (sender == null) {
Expand Down Expand Up @@ -1281,6 +1282,7 @@ public String lootValueSheet(@Me IMessageIO io, @Me GuildDB db, Set<DBNation> at
@NoFormat
public static String mail(@Me DBNation me, @Me JSONObject command, @Me GuildDB db, @Me IMessageIO channel, @Me User author, Set<DBNation> nations, String subject, @TextArea String message, @Switch("f") boolean confirm, @Arg("Send from the api key registered to the guild") @Switch("l") boolean sendFromGuildAccount, @Arg("The api key to use to send the mail") @Switch("a") String apiKey) throws IOException {
message = MarkupUtil.transformURLIntoLinks(message);
GPTUtil.checkThrowModeration(message);

ApiKeyPool.ApiKey myKey = me.getApiKey(false);

Expand Down Expand Up @@ -1673,6 +1675,9 @@ public String mailCommandOutput(NationPlaceholders placeholders, ValueStore stor
if (sheet == null) {
sheet = SpreadSheet.create(db, SheetKey.MAIL_RESPONSES_SHEET);
}
if (body != null) {
GPTUtil.checkThrowModeration(body);
}

List<String> header = new ArrayList<>(Arrays.asList(
"nation",
Expand Down Expand Up @@ -1802,6 +1807,10 @@ public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO i
int applicants = 0;

Map<DBNation, Map.Entry<String, String>> messageMap = new LinkedHashMap<>();
if (force) {
String messagesJoined = messageMap.values().stream().map(e -> e.getKey() + " " + e.getValue()).collect(Collectors.joining("\n"));
GPTUtil.checkThrowModeration(messagesJoined);
}

for (int i = 1; i < nationNames.size(); i++) {
Object nationNameObj = nationNames.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import link.locutus.discord.db.entities.DBAlliance;
import link.locutus.discord.db.guild.GuildKey;
import link.locutus.discord.db.guild.SheetKey;
import link.locutus.discord.gpt.GPTUtil;
import link.locutus.discord.pnw.AllianceList;
import link.locutus.discord.pnw.BeigeReason;
import link.locutus.discord.pnw.NationList;
Expand Down Expand Up @@ -3186,6 +3187,9 @@ public String mailTargets(@Me GuildDB db, @Me Guild guild, @Me JSONObject comman
@Arg("Parse nation leader instead of nation name") @Switch("l") boolean useLeader,
@Arg("Send instructions as direct message on discord")
@Switch("d") boolean dm) throws IOException, GeneralSecurityException {
if(header != null) {
GPTUtil.checkThrowModeration(header);
}

ApiKeyPool.ApiKey myKey = me.getApiKey(false);
ApiKeyPool key = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import link.locutus.discord.db.GuildDB;
import link.locutus.discord.db.entities.DBNation;
import link.locutus.discord.db.guild.GuildKey;
import link.locutus.discord.gpt.GPTUtil;
import link.locutus.discord.pnw.Spyop;
import link.locutus.discord.user.Roles;
import link.locutus.discord.util.*;
Expand Down Expand Up @@ -102,6 +103,9 @@ public String onCommand(Guild guild, IMessageIO channel, User author, DBNation m

if (!Roles.MAIL.has(author, guild)) return "You need the MAIL role on discord (see " + CM.role.setAlias.cmd.toSlashMention() + ") to add the custom message: `" + header + "`";
}
if(header != null && !header.isEmpty()) {
GPTUtil.checkThrowModeration(header);
}

Map<DBNation, Set<DBNation>> warAttDefMap = BlitzGenerator.reverse(warDefAttMap);
Map<DBNation, Set<DBNation>> spyAttDefMap = BlitzGenerator.reverse(spyDefAttMap);
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/link/locutus/discord/config/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ public class Settings extends Config {
@Comment("Your P&W password (optional, but recommended)")
public String PASSWORD = "";

@Comment("Your P&W verified bot key (optional)")
@Comment({"Your P&W verified bot key (optional)",
"Needed to perform ingame actions such as banking",
"Open a ticket in the Politics And Programming server to obtain a key"})
public String ACCESS_KEY = "";

@Comment("Your api key (generated if username/password is set)")
Expand Down
96 changes: 77 additions & 19 deletions src/main/java/link/locutus/discord/gpt/GPTModerator.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package link.locutus.discord.gpt;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.knuddels.jtokkit.api.ModelType;
import com.theokanning.openai.moderation.ModerationCategories;
import com.theokanning.openai.moderation.ModerationCategoryScores;
import com.theokanning.openai.service.OpenAiService;
import com.theokanning.openai.moderation.Moderation;
import com.theokanning.openai.moderation.ModerationRequest;
import link.locutus.discord.config.Settings;
import link.locutus.discord.util.FileUtil;
import link.locutus.discord.util.StringMan;
import link.locutus.discord.util.io.PagePriority;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand All @@ -31,10 +37,22 @@ public GPTModerator(OpenAiService service) {
public List<Moderation> checkModeration(String input) {
return service.createModeration(ModerationRequest.builder().input(input).build()).getResults();
}

@Override
public List<ModerationResult> moderate(List<String> inputs) {
List<String> split = new ArrayList<>();
for (String input : inputs) {
int tokens = GPTUtil.getTokens(input, ModelType.GPT_3_5_TURBO);
if (tokens > 2000) {
List<String> parts = GPTUtil.getChunks(input, ModelType.GPT_3_5_TURBO, 2000);
split.addAll(parts);
} else {
split.add(input);
}
}

List<ModerationResult> results = new ArrayList<>();
JSONObject response = checkModeration(inputs);
JSONObject response = checkModeration(split);
if (response.has("error")) {
ModerationResult errorResult = new ModerationResult();
errorResult.setError(true);
Expand Down Expand Up @@ -68,24 +86,64 @@ public List<ModerationResult> moderate(List<String> inputs) {
return results;
}

public JSONObject checkModeration(List<String> inputs) {
String url = "https://api.openai.com/v1/moderations";
String apiKey = Settings.INSTANCE.ARTIFICIAL_INTELLIGENCE.OPENAI.API_KEY;

Map<String, List<String>> arguments = new HashMap<>();
arguments.put("input", inputs);

Consumer<HttpURLConnection> apply = connection -> {
connection.setRequestProperty("Authorization", "Bearer " + apiKey);
connection.setRequestProperty("Content-Type", "application/json");
};

JSONObject argsJs = new JSONObject(arguments);
byte[] dataBinary = argsJs.toString().getBytes(StandardCharsets.UTF_8);
public void addToObject(Object classWithProperties, JSONObject categoriesObject) {
for (Field field : classWithProperties.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(JsonProperty.class)) {
try {
field.setAccessible(true);
categoriesObject.put(field.getName(), field.get(classWithProperties));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

CompletableFuture<String> result = FileUtil.readStringFromURL(PagePriority.GPT_MODERATE, url, dataBinary, FileUtil.RequestType.POST, null, apply);
String jsonStr = FileUtil.get(result);
// parse to JSONObject (org.json)
return new JSONObject(jsonStr);
public JSONObject checkModeration(List<String> inputs) {
List<Moderation> all = new ArrayList<>();
for (String input : inputs) {
System.out.println("Moderating: " + input);
List<Moderation> moderations = checkModeration(input);
all.addAll(moderations);
}
// construct json
JSONObject response = new JSONObject();
JSONArray resultsArray = new JSONArray();
for (Moderation moderation : all) {
System.out.println(moderation);
JSONObject resultObject = new JSONObject();
resultObject.put("flagged", moderation.isFlagged());
if (moderation.isFlagged()) {
JSONObject categoriesObject = new JSONObject();
ModerationCategories category = moderation.getCategories();
addToObject(category, categoriesObject);
resultObject.put("categories", categoriesObject);
JSONObject categoryScoresObject = new JSONObject();
ModerationCategoryScores categoryScores = moderation.getCategoryScores();
addToObject(categoryScores, categoryScoresObject);
resultObject.put("category_scores", categoryScoresObject);
}
resultsArray.put(resultObject);
}
response.put("results", resultsArray);
return response;
// String url = "https://api.openai.com/v1/moderations";
// String apiKey = Settings.INSTANCE.ARTIFICIAL_INTELLIGENCE.OPENAI.API_KEY;
//
// Map<String, List<String>> arguments = new HashMap<>();
// arguments.put("input", inputs);
//
// Consumer<HttpURLConnection> apply = connection -> {
// connection.setRequestProperty("Authorization", "Bearer " + apiKey);
// connection.setRequestProperty("Content-Type", "application/json");
// };
//
// JSONObject argsJs = new JSONObject(arguments);
// byte[] dataBinary = argsJs.toString().getBytes(StandardCharsets.UTF_8);
//
// CompletableFuture<String> result = FileUtil.readStringFromURL(PagePriority.GPT_MODERATE, url, dataBinary, FileUtil.RequestType.POST, null, apply);
// String jsonStr = FileUtil.get(result);
// // parse to JSONObject (org.json)
// return new JSONObject(jsonStr);
}
}
2 changes: 2 additions & 0 deletions src/main/java/link/locutus/discord/gpt/GPTUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.theokanning.openai.moderation.ModerationRequest;
import link.locutus.discord.Locutus;
import link.locutus.discord.gpt.pw.PWGPTHandler;
import link.locutus.discord.util.MathMan;
import link.locutus.discord.util.StringMan;

import java.util.ArrayList;
Expand Down Expand Up @@ -37,6 +38,7 @@ public static void checkThrowModeration2(List<Moderation> moderations, String te
}

public static void checkThrowModeration(String text) {
if (text == null || text.isEmpty() || MathMan.isInteger(text)) return;
PWGPTHandler gpt = Locutus.imp().getCommandManager().getV2().getPwgptHandler();
if (gpt != null) {
GptHandler handler = gpt.getHandler();
Expand Down

0 comments on commit 9aee4a2

Please sign in to comment.