Skip to content
Merged
66 changes: 64 additions & 2 deletions src/__mocks__/discord.js.ts
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited this file quite a bit to fix mocks, but they really, really need to be refactored soon.

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@ import { Client, ClientOptions, GuildManager, RESTOptions, UserFlagsBitField } f
const discordJS = jest.requireActual<typeof import("discord.js")>("discord.js");
const mockDiscordJS = jest.createMockFromModule<typeof import("discord.js")>("discord.js");

// types
mockDiscordJS.MessageFlags = discordJS.MessageFlags;
mockDiscordJS.EmbedBuilder = discordJS.EmbedBuilder;
mockDiscordJS.ApplicationCommandOptionType = discordJS.ApplicationCommandOptionType;
mockDiscordJS.GatewayIntentBits = discordJS.GatewayIntentBits;
mockDiscordJS.UserFlags = discordJS.UserFlags;
mockDiscordJS.ApplicationCommandType = discordJS.ApplicationCommandType;
mockDiscordJS.ComponentType = discordJS.ComponentType;

// classes
mockDiscordJS.Collection = discordJS.Collection;

// embeds
mockDiscordJS.ActionRowBuilder = discordJS.ActionRowBuilder;
mockDiscordJS.EmbedBuilder = discordJS.EmbedBuilder;
mockDiscordJS.ButtonStyle = discordJS.ButtonStyle;
mockDiscordJS.StringSelectMenuBuilder = discordJS.StringSelectMenuBuilder;
mockDiscordJS.StringSelectMenuOptionBuilder = discordJS.StringSelectMenuOptionBuilder;
mockDiscordJS.ButtonBuilder = discordJS.ButtonBuilder;

Object.defineProperty(mockDiscordJS, "Routes", {
writable: true,
value: {
Expand Down Expand Up @@ -111,9 +122,60 @@ class MockClientUser {
}
};

// class MockStringSelectMenuBuilder extends discordJS.StringSelectMenuBuilder {
// constructor() {
// super();
// }

// public setLabel(label: string): this {
// return this;
// }

// public setDescription(description: string): this {
// return this;
// }

// public setCustomId(customId: string): this {
// return this;
// }
// }

// class MockStringSelectMenuOptionBuilder extends discordJS.StringSelectMenuOptionBuilder {
// constructor() {
// super();
// }

// public setLabel(label: string): this {
// return this;
// }

// public setValue(value: string): this {
// return this;
// }

// public setDescription(description: string): this {
// return this;
// }
// }

// class MockButtonBuilder extends discordJS.ButtonBuilder {
// constructor() {
// super();
// }

// public setCustomId(customId: string): this {
// return this;
// }

// public setLabel(label: string): this {
// return this;
// }

// public setStyle(style: ButtonStyle): this {
// return this;
// }
// }

// @ts-ignore
mockDiscordJS.REST = MockREST;
mockDiscordJS.Client = MockClient as unknown as typeof discordJS.Client;
mockDiscordJS.ClientUser = MockClientUser as unknown as typeof discordJS.ClientUser;
Expand Down
6 changes: 5 additions & 1 deletion src/discordApp.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "dotenv/config";
import { Client, GatewayIntentBits, Events } from "discord.js";
import { clarify, embed, ping, tone, requestAnonymousClarification, mood } from "./interactions"
import { clarify, embed, ping, tone, requestAnonymousClarification, mood, inDepthClarification, postemptiveToneAdd, getTones, action } from "./interactions"
import { cleanupMoods } from "./helpers";

export async function launchBot(): Promise<Client> {
Expand Down Expand Up @@ -57,10 +57,14 @@ export async function launchBot(): Promise<Client> {
if (interaction.isChatInputCommand()) { // slash command
if (interaction.commandName === "ping") await ping(interaction);
if (interaction.commandName === "embed") await embed(interaction);
if (interaction.commandName === "action") await action(interaction);
if (interaction.commandName === "list-tones") await getTones(interaction);
if (interaction.commandName === "mood") await mood(interaction);
} else if (interaction.isMessageContextMenuCommand()) { // command from the "apps" menu when clicking on a message
if (interaction.commandName === "Tone") await tone(interaction);
if (interaction.commandName === "Add Tone") await postemptiveToneAdd(interaction);
if (interaction.commandName === "Clarify") await clarify(interaction);
if (interaction.commandName === "In-Depth Clarification") await inDepthClarification(interaction);
if (interaction.commandName === "Request Anonymous Clarification") await requestAnonymousClarification(interaction);
} else {
console.log(interaction);
Expand Down
99 changes: 99 additions & 0 deletions src/gptRequests.ts
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may come back to this later to modify the GPT prompts, but it looks good for now.

Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,105 @@ export async function analyzeTone(userText: string): Promise<string> {
}
}

export async function explanationOfTone(userText: string): Promise<string> {
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
"role": "system",
"content": [
{
"type": "text",
"text": `
Humans are unpredictable beings. A text message by someone can be interpreted as passive aggressive
or cheerful depending on how the person reads it in their minds. This can lead to misunderstandings.
However, assume you are an expert in understanding human emotions when they send text messages.
I want you to reply to the following texts by giving your best guess about what the person might be
feeling when they wrote it. You are to figure out whether they are sad, mad, happy, neutral, or any
other emotion that the person is conveying. Assume the texter is familiar with the modern day texting conventions.
Sometimes, the text will contain "@vibecheque". You are to discard that, and only analyze
the rest of the text.

I want you to analyze the text with the intention of clarifying the message to solve the aformentioned issues.
For any tone in the message, I want you to format your explanation as following:

> "text" <tone>

If the message has fragments with different tone, I want you to use the following format instead:

> "text fragment" <fragment tone>

After the tone, I want you to explain how the tone applies to respective fragment in a single sentence.
After the analysis, I want you to include some variation of "Hope that clears things up!"
`
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": userText
}
]
}
]
});

if (response.choices[0].message.content !== null){
return response.choices[0].message.content;
}
else{
return "Unknown error - can't explain tone at the moment"
}
}

export async function emojiRepresentation(userText: string): Promise<string> {
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
"role": "system",
"content": [
{
"type": "text",
"text": `
Humans are unpredictable beings. A text message by someone can be interpreted as passive aggressive
or cheerful depending on how the person reads it in their minds. This can lead to misunderstandings.
However, assume you are an expert in understanding human emotions when they send text messages.
I want you to reply to the following texts by giving your best guess about what the person might be
feeling when they wrote it. You are to figure out whether they are sad, mad, happy, neutral, or any
other emotion that the person is conveying. Assume the texter is familiar with the modern day texting conventions.
Sometimes, the text will contain "@vibecheque". You are to discard that, and only analyze
the rest of the text.

I want you to tune into the tone behind any messages you receive and reply only with the emoji which best fits.
If you are unable to determine an emoji for the message, respond only with this emoji: 🛒
`
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": userText
}
]
}
]
});

if (response.choices[0].message.content !== null){
return response.choices[0].message.content;
}
else{
return "Unknown error - can't generate emojis at the moment"
}
}

// wrapper for determining the color of a given tone
// TODO: avoid common background colors
export async function analyzeMoodColor(mood: string): Promise<string> {
Expand Down
Loading