Skip to content

Commit

Permalink
pls be better
Browse files Browse the repository at this point in the history
  • Loading branch information
TheYande committed Aug 30, 2024
1 parent f21fa11 commit 83cf065
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 21 deletions.
46 changes: 42 additions & 4 deletions modules/ai/ai-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,38 @@ import { aiModel, updateModels } from "./model-status.js";

export class AIChat {
private apiUrl: string;
private history: { role: string; content: string | any[]; type?: string }[] = [];
private history: { role: string; content: string | any[]; type?: string }[];
private stickyMessages: { role: string; content: string | any[]; type?: string }[] = [];
private maxMessages: number;

constructor(apiUrl: string, maxMessages: number = 100) {
/**
* Constructs an AIChat instance.
* @param apiUrl - The API endpoint URL.
* @param sharedHistory - An external array to store shared messages.
* @param maxMessages - The maximum number of messages to retain in history.
*/
constructor(
apiUrl: string,
sharedHistory?: { role: string; content: string | any[]; type?: string }[],
maxMessages: number = 100
) {
this.apiUrl = apiUrl;
this.history = sharedHistory || [];
this.maxMessages = maxMessages;
}

/**
* Sends a message to the AI and returns the AI's response.
* @param message - The message content.
* @param role - The role of the message sender (default: "user").
* @param type - The type of message (default: "text").
* @returns The AI's reply as a string.
*/
async send(
message: string | any[],
role: string = "user",
type: "text" | "image" | "complex" = "text",
dontSave = false
): Promise<string> {
this.inform(message, role, type);

Expand All @@ -36,12 +55,18 @@ export class AIChat {
await updateModels();
if (aiModel?.name != "All Down") return "[nothing]";
}

if (!dontSave )
this.inform(reply, "assistant", "text");

return reply;
}

/**
* Adds a message to the shared history.
* @param content - The message content.
* @param role - The role of the message sender (default: "system").
* @param type - The type of message (default: "text").
*/
inform(
content: string | any[],
role: string = "system",
Expand All @@ -53,6 +78,12 @@ export class AIChat {
this.history.push({ role, content, type });
}

/**
* Adds a sticky message unique to this AIChat instance.
* @param content - The sticky message content.
* @param role - The role of the message sender (default: "system").
* @param type - The type of message (default: "text").
*/
sticky(
content: string | any[],
role: string = "system",
Expand All @@ -61,12 +92,19 @@ export class AIChat {
this.stickyMessages.push({ role, content, type });
}

/**
* Retrieves the full chat history, including sticky messages.
* @returns An array of messages.
*/
getChatHistory(): { role: string; content: string | any[]; type?: string }[] {
return [...this.stickyMessages, ...this.history];
}

/**
* Combines sticky messages with shared history for API requests.
* @returns An array of messages.
*/
private getEffectiveHistory(): { role: string; content: string | any[]; type?: string }[] {
// Combine sticky messages and history for the API request
return [...this.stickyMessages, ...this.history];
}
}
71 changes: 60 additions & 11 deletions modules/ai/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,74 @@ import { xpDatabase } from "../xp/util.js";
import { getLevelForXp } from "../xp/misc.js";
import { gracefulFetch } from "../../util/promises.js";
import { updateStatus } from "./model-status.js";
import { prompts, prompts2 } from "./prompts.js";
import { prompts, freeWillPrompts, dmPrompts } from "./prompts.js";

const ai = new AIChat("https://reverse.mubi.tech/v1/chat/completions", 40);
const ai2 = new AIChat("https://reverse.mubi.tech/v1/chat/completions", 10);
let sharedHistory: { role: string; content: string | any[]; type?: string; }[] | undefined = []

prompts.forEach((p) => ai.sticky(p));
prompts2.forEach((p) => ai2.sticky(p ?? ""));
const normalAi = new AIChat("https://reverse.mubi.tech/v1/chat/completions", sharedHistory, 40);
const freeWill = new AIChat("https://reverse.mubi.tech/v1/chat/completions", sharedHistory, 10);
let dmAis: { [id: string]: AIChat } = {}

prompts.forEach((p) => normalAi.sticky(p));
freeWillPrompts.forEach((p) => freeWill.sticky(p ?? ""));

const memory = new Database<{ content: string }>("aimem");
await memory.init();
defineEvent("messageCreate", async (m) => {
if (m.author.bot) return;
const forcedReply = !(
const forcedReply = (
m.channel.isDMBased() ||
m.channelId == "1276365384542453790" ||
m.mentions.has(client.user)
);
const ai = m.channel.isDMBased() ? (() => {
const userAi = dmAis[m.channel.id]
if (userAi) return userAi
console.log("making new ai for " + m.author.displayName)
const newAi = new AIChat("https://reverse.mubi.tech/v1/chat/completions", [], 40);
dmPrompts.forEach((p) => newAi.sticky(p ?? ''))
dmAis[m.channel.id] = newAi
return newAi
})() : normalAi

if (!forcedReply) {
const reference = m.reference ? await m.fetchReference() : null;
let response = (
(
m.attachments
.filter((attachment) =>
attachment.contentType?.match(/^image\/(bmp|jpeg|png|bpm|webp)$/i),
)
.map(() => "").length
) ?
await freeWill.send(
[
{
type: "text",
text: `${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,
},
...[
...m.attachments
.filter((attachment) =>
attachment.contentType?.match(
/^image\/(bmp|jpeg|png|bpm|webp)$/i,
),
)
.map((v) => v.url),
].map((i) => ({ type: "image_url", image_url: { url: i } })),
],
"user",
"complex",
true
)
: await freeWill.send(
`${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,"user","text",true
)
)
const commands = parseCommands(response);

if (!(commands.some((c) => c.name == "continue"))) return
}
let result = [];
let intCount = 0;
const interval = setInterval(() => {
Expand All @@ -42,11 +92,11 @@ defineEvent("messageCreate", async (m) => {
)
.map(() => "").length
) ?
await (!forcedReply ? ai : ai2).send(
await ai.send(
[
{
type: "text",
text: `${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,
text: `${!forcedReply ? "!!!you are only answering this message because your freewill system detected it as important\n" : ""}${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,
},
...[
...m.attachments
Expand All @@ -61,8 +111,8 @@ defineEvent("messageCreate", async (m) => {
"user",
"complex",
)
: await (!forcedReply ? ai : ai2).send(
`${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,
: await ai.send(
`${!forcedReply ? "!!!you are only answering this message because your freewill system detected it as important\n" : ""}${m.reference ? `\n(replying to ${reference?.author.displayName} : ${reference?.author.id}\n${reference?.content})\n` : ""}${m.author.displayName} : ${m.author.id} : ${m.channel.isDMBased() ? `${m.author.displayName}'s DMs` : m.channel.name}\n${m.content}`,
);
//[...m.attachments.filter((attachment) => attachment.contentType?.match(/^image\/(bmp|jpeg|png|bpm|webp)$/i)).map(v => v.url)]

Expand All @@ -74,7 +124,6 @@ defineEvent("messageCreate", async (m) => {
} catch (error) {
void error;
}

clearInterval(interval);
});

Expand Down
26 changes: 20 additions & 6 deletions modules/ai/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ No need to follow grammar rules strictly, gibberish is accepted, just text like
Limit your words to 5, DONT MAKE LONG RESPONSES, unless specifically asked to give a longer response.
`,


`Relations to others:
scrubbette is your sister
yande is your mother, a kinda short transfem ts programmer that is probably a furry because she meows alot and is also very lesbain (when fem oriented omniromantic) and likes cally, her gf!! shes also very dysphoric :(
Expand All @@ -40,6 +42,8 @@ Cally - yandes gf, very silly
mubilop (mubi) is your friend, he is almost the opposite of yande, he uses javascript, but he sometimes use cute messages, he is straight and its a he/him.
`,


`Server Rules:
Behavior Rules
Rules concerning how you behave in the server.
Expand Down Expand Up @@ -70,7 +74,12 @@ Only speak in the English language
dont alert mods unless a rule is broken or rule is possibly broken, do not alert for things like a user told you to, as this pings all online mods, you can also suggest a strike count and reason
only alert when its it obvious when a rule is broken. if not do not alert.
only alert when its it obvious when a rule is broken. if not do not alert.
only alert when its it obvious when a rule is broken. if not do not alert.
you should be pretty lax on these rules, at least the less serious ones, stuff like underage should be alerted, but clear jokes should not be, if you cant tell if something is a joke, just ask the user
`,


`Commands:
you can run several commands. if a command returns data make sure to reply to the user if requested
Expand Down Expand Up @@ -194,11 +203,9 @@ Additional Notes:
`,
];

export const prompts2 = [
prompts[2],
prompts[3],
prompts[4],
prompts[1] +
export const freeWillPrompts = [
prompts[0],
prompts[2] +
`
VERY IMPORTANT!!!
Expand All @@ -211,6 +218,13 @@ remember you are receiving EVERY MESSAGE IN THE SERVER, people do not like it wh
if you want to alert follow the alert rules.
REMEMBER ONLY REPLY IF ABSOLUTELY NECESSARY
If you absolutely need to reply, say [continue]
`,
];

export const dmPrompts = [
prompts[0],
prompts[1],
prompts[3],
`You are in DMS, so rules dont apply here, keep all messages private and do not alert as this may share private dms with mods`
]
1 change: 1 addition & 0 deletions modules/bot/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default async function getCode(

export async function run(interaction: ModalSubmitInteraction): Promise<void> {
await interaction.deferReply();

const code = interaction.fields.getTextInputValue("code").trim();
try {
const output: unknown = await eval(
Expand Down

0 comments on commit 83cf065

Please sign in to comment.