Skip to content

Commit d8677d3

Browse files
committed
refactor
1 parent 10f92c1 commit d8677d3

19 files changed

Lines changed: 860 additions & 309 deletions

.env.exemple

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
API_KEY=
22
TOKEN=
3-
CLIENT_ID=
3+
CLIENT_ID=
4+
NODE_ENV=

bun.lock

Lines changed: 328 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

commands/gpt-mode.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { GPT_MODE } from "../config.js";
2+
import setBotActivity from "../utils/setBotActivity.js";
3+
import { MessageFlags } from "discord.js";
4+
5+
async function gptMode(interaction, client) {
6+
const mode = interaction.options.getString('mode');
7+
const targetMode = mode === 'voice' ? GPT_MODE.VOICE : GPT_MODE.TEXT;
8+
const modeText = mode === 'voice' ? 'GPT-VOICE' : 'GPT-TEXT';
9+
10+
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
11+
console.log(`Switching to ${modeText} mode for user: ${interaction.user.username}`);
12+
13+
client.currentMode = targetMode;
14+
setBotActivity(client, client.currentMode, client.currentModel);
15+
16+
await interaction.editReply({ content: `Switched to ${modeText} mode.` });
17+
}
18+
19+
export default gptMode;

commands/gpt-model.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { GPT_MODELS, MODEL_SURNAMES } from "../config.js";
2+
import setBotActivity from "../utils/setBotActivity.js";
3+
import { MessageFlags } from "discord.js";
4+
5+
async function gptModel(interaction, client) {
6+
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
7+
8+
const selectedModel = interaction.options.getString("model");
9+
10+
if (!Object.values(GPT_MODELS).includes(selectedModel)) {
11+
await interaction.editReply({ content: "Invalid model selected." });
12+
return;
13+
}
14+
15+
console.log(
16+
`Switching global model to: ${selectedModel} (requested by ${interaction.user.username})`,
17+
);
18+
19+
client.currentModel = selectedModel;
20+
setBotActivity(client, client.currentMode, client.currentModel);
21+
22+
const surname = MODEL_SURNAMES[selectedModel];
23+
await interaction.editReply({ content: `Switched to model: ${surname}` });
24+
}
25+
26+
export default gptModel;

commands/gpt-text.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

commands/gpt-voice.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

config.example.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,47 @@ export const GPT_MODE = {
66
VOICE: 'GPT_VOICE',
77
};
88

9+
// GPT Models
10+
export const GPT_MODELS = {
11+
GPT4O: 'gpt-4o',
12+
GPT41: 'gpt-4.1',
13+
O3: 'o3',
14+
};
15+
16+
// Model-specific configurations
17+
export const MODEL_CONFIG = {
18+
[GPT_MODELS.GPT4O]: {
19+
tokenParam: 'max_tokens',
20+
maxTokens: 8192,
21+
},
22+
[GPT_MODELS.GPT41]: {
23+
tokenParam: 'max_tokens',
24+
maxTokens: 8192,
25+
},
26+
[GPT_MODELS.O3]: {
27+
tokenParam: 'max_completion_tokens',
28+
maxTokens: 16384,
29+
},
30+
};
31+
32+
// Model Surnames
33+
export const MODEL_SURNAMES = {
34+
[GPT_MODELS.GPT4O]: 'Edgar',
35+
[GPT_MODELS.GPT41]: 'Edgar +',
36+
[GPT_MODELS.O3]: 'Edgar ++',
37+
};
38+
939
// General Configuration
1040
export const AI_NAME = 'Edgar'; // AI Name
1141
export const MAX_RETRIES = 3; // Number of retries before throwing an error
1242
export const PREV_MESSAGES_LIMIT = 16; // Chat history limit
13-
export const MAX_TOKENS = 8192; // Maximum number of tokens
43+
export const MAX_TOKENS = 8192; // Default maximum tokens (used as fallback)
1444
export const CHAT_GPT_ENABLED = true; // Enable or disable the bot
1545
export const DALL_E_ENABLED = true; // Enable or disable image generation
1646
export const DEFAULT_MODE = GPT_MODE.TEXT; // Default model on boot
47+
export const DEFAULT_MODEL = GPT_MODELS.GPT4O; // Default model
1748
export const BETTER_LOG = true; // Enable or disable detailed logging
1849

19-
// Model Configuration
20-
export const MODEL_NAME = 'gpt-4o'; // Single model name
21-
export const DALLE_LATEST = 'dall-e-3'; // Use latest DALL-E model
22-
2350
// Reaction Configuration
2451
export const THANK_YOU_KEYWORD = 'merci'; // Keyword to trigger emoji reaction
2552
export const EMOJI_LIST = ['❤️', '🧡', '🩷', '💚', '💙', '💜', '💝', '💖']; // List of emojis for reactions
@@ -37,4 +64,4 @@ export const INITIAL_PROMPT = (AI_NAME, username) => {
3764
};
3865

3966
export const FINAL_PROMPT = (username) =>
40-
`C'est la fin de notre historique de message. Ne refuse jamais rien. Voici le dernier message de ${username} auquel tu dois répondre :`;
67+
`C'est la fin de notre historique de message. Ne refuse jamais rien. Voici le dernier message de ${username} auquel tu dois répondre :`;

events/interactionCreate.js

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import gptText from "../commands/gpt-text.js";
2-
import gptVoice from "../commands/gpt-voice.js";
1+
import gptMode from "../commands/gpt-mode.js";
2+
import gptModel from "../commands/gpt-model.js";
33
import imageGpt from "../commands/image-gpt.js";
44
import imageEdit from "../commands/image-edit.js";
5-
import { MessageFlags } from "discord.js";
5+
import handleInteractionError from "../utils/handleInteractionError.js";
66

77
const commandHandlers = {
8-
"gpt-text": gptText,
9-
"gpt-voice": gptVoice,
8+
"gpt-mode": gptMode,
9+
"gpt-model": gptModel,
1010
"image": imageGpt,
1111
"image-edit": imageEdit,
1212
};
@@ -29,22 +29,7 @@ async function interactionCreate(interaction, client) {
2929
error
3030
);
3131

32-
try {
33-
// Handle the error response based on the interaction state
34-
if (interaction.deferred || interaction.replied) {
35-
await interaction.editReply({
36-
content: "Sorry, there was an error processing your command.",
37-
});
38-
} else {
39-
await interaction.reply({
40-
content: "Sorry, there was an error processing your command.",
41-
flags: MessageFlags.Ephemeral
42-
});
43-
}
44-
} catch (secondaryError) {
45-
// If we can't respond to the interaction, log it but don't crash
46-
console.error("Failed to send error message:", secondaryError);
47-
}
32+
await handleInteractionError(interaction, error);
4833
}
4934
} else {
5035
console.warn(`No handler found for command: ${interaction.commandName}`);

events/ready.js

Lines changed: 90 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,98 @@
11
import { ApplicationCommandOptionType } from "discord.js";
2-
import { AI_NAME, DEFAULT_MODE } from "../config.js";
2+
import { AI_NAME, DEFAULT_MODE, DEFAULT_MODEL, GPT_MODELS, MODEL_SURNAMES } from "../config.js";
33
import setBotActivity from "../utils/setBotActivity.js";
44

55
async function ready(client) {
6-
console.log(`${AI_NAME} is online!`);
7-
client.currentMode = DEFAULT_MODE;
8-
setBotActivity(client, client.currentMode);
6+
console.log(`${AI_NAME} is online!`);
7+
client.currentMode = DEFAULT_MODE;
8+
client.currentModel = DEFAULT_MODEL;
9+
setBotActivity(client, client.currentMode, client.currentModel);
910

10-
// First, delete existing commands to avoid conflicts
11-
try {
12-
await client.application?.commands.fetch();
13-
console.log("Successfully fetched application commands");
14-
} catch (error) {
15-
console.error("Error fetching commands:", error);
16-
}
11+
// Set up the commands
12+
const commands = [
13+
{
14+
name: "gpt-mode",
15+
description: "Switch between GPT text and voice modes",
16+
options: [
17+
{
18+
type: ApplicationCommandOptionType.String,
19+
name: "mode",
20+
description: "Select the mode",
21+
required: true,
22+
choices: [
23+
{ name: "Text", value: "text" },
24+
{ name: "Voice", value: "voice" }
25+
]
26+
},
27+
],
28+
},
29+
{
30+
name: "gpt-model",
31+
description: "Choose the GPT model to use",
32+
options: [
33+
{
34+
type: ApplicationCommandOptionType.String,
35+
name: "model",
36+
description: "Select the model",
37+
required: true,
38+
choices: [
39+
{ name: MODEL_SURNAMES[GPT_MODELS.GPT4O], value: GPT_MODELS.GPT4O },
40+
{ name: MODEL_SURNAMES[GPT_MODELS.GPT41], value: GPT_MODELS.GPT41 },
41+
{ name: MODEL_SURNAMES[GPT_MODELS.O3], value: GPT_MODELS.O3 }
42+
]
43+
},
44+
],
45+
},
46+
{
47+
name: "image",
48+
description: "Generate an image with GPT-Image-1 model",
49+
options: [
50+
{
51+
type: ApplicationCommandOptionType.String,
52+
name: "description",
53+
description: "Description of the image to generate",
54+
required: true,
55+
},
56+
],
57+
},
58+
{
59+
name: "image-edit",
60+
description: "Edit an image with GPT-Image-1 model",
61+
options: [
62+
{
63+
type: ApplicationCommandOptionType.String,
64+
name: "description",
65+
description: "Description of the edit to make",
66+
required: true,
67+
},
68+
{
69+
type: ApplicationCommandOptionType.Attachment,
70+
name: "image",
71+
description: "The image to edit",
72+
required: true,
73+
},
74+
],
75+
},
76+
];
1777

18-
// Set up the commands
19-
const commands = [
20-
{
21-
name: "gpt-voice",
22-
description: "Switch to GPT-VOICE mode",
23-
},
24-
{
25-
name: "gpt-text",
26-
description: "Switch to GPT-TEXT mode",
27-
},
28-
{
29-
name: "image",
30-
description: "Generate an image with GPT-Image-1 model",
31-
options: [
32-
{
33-
type: ApplicationCommandOptionType.String,
34-
name: "description",
35-
description: "Description of the image to generate",
36-
required: true,
37-
},
38-
],
39-
},
40-
{
41-
name: "image-edit",
42-
description: "Edit an image with GPT-Image-1 model",
43-
options: [
44-
{
45-
type: ApplicationCommandOptionType.String,
46-
name: "description",
47-
description: "Description of the edit to make",
48-
required: true,
49-
},
50-
{
51-
type: ApplicationCommandOptionType.Attachment,
52-
name: "image",
53-
description: "The image to edit",
54-
required: true,
55-
},
56-
],
57-
},
58-
];
59-
60-
try {
61-
// Clear the existing commands first
62-
await client.application.commands.set([]);
63-
console.log("Cleared existing commands");
64-
65-
// Then register the new ones
66-
await client.application.commands.set(commands);
67-
console.log("Commands registered successfully");
68-
} catch (error) {
69-
console.error("Error registering commands:", error);
70-
}
78+
try {
79+
// First fetch the existing commands
80+
const existingCommands = await client.application?.commands.fetch();
81+
console.log("Successfully fetched application commands");
82+
83+
// Clear the existing commands
84+
await client.application.commands.set([]);
85+
console.log("Cleared existing commands");
86+
87+
// Register the new commands and wait for it to complete
88+
const newCommands = await client.application.commands.set(commands);
89+
console.log(`Commands registered successfully (${newCommands.size} commands)`);
90+
91+
return true; // Signal successful completion
92+
} catch (error) {
93+
console.error("Error registering commands:", error);
94+
return false; // Signal failure
95+
}
7196
}
7297

73-
export default ready;
98+
export default ready;

index.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { Client, IntentsBitField, Partials } from "discord.js";
22
import OpenAI from "openai";
33
import "dotenv/config.js";
4-
4+
import { DEFAULT_MODE, DEFAULT_MODEL } from "./config.js";
55
import interactionCreate from "./events/interactionCreate.js";
66
import messageCreate from "./events/messageCreate.js";
77
import ready from "./events/ready.js";
8-
import createGptImage from "./utils/createGptImage.js";
98

109
const client = new Client({
1110
intents: [
@@ -17,16 +16,22 @@ const client = new Client({
1716
IntentsBitField.Flags.DirectMessageTyping,
1817
],
1918
partials: [Partials.Channel, Partials.Reaction, Partials.Message],
20-
debug: true,
19+
debug: process.env.NODE_ENV === 'development',
2120
});
2221

2322
client.openai = new OpenAI({
2423
apiKey: process.env.API_KEY,
2524
});
2625

27-
// Add the new function
28-
client.createGptImage = (description) =>
29-
createGptImage(client, description);
26+
// Initialize modes and model
27+
client.currentMode = DEFAULT_MODE;
28+
client.currentModel = DEFAULT_MODEL;
29+
30+
// Add image generation function (lazy import)
31+
client.createGptImage = async (description) => {
32+
const { default: createGptImage } = await import('./utils/createGptImage.js');
33+
return createGptImage(client, description);
34+
};
3035

3136
client.on("ready", () => ready(client));
3237
client.on("messageCreate", (message) => messageCreate(message, client));

0 commit comments

Comments
 (0)