diff --git a/src/execution.ts b/src/execution.ts index ca0f303..434a76c 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -5,16 +5,20 @@ import Moderation from "./moderation"; import config from "./config"; import toOpenAIMessages from "./toOpenAIMessages"; +type NonNullableInObject = { [k in keyof T]: k extends V ? NonNullable : T[k] }; +type apiRequest = DiscordApi.Message | DiscordApi.RepliableInteraction; +export type request = apiRequest & NonNullableInObject; + /** Stores the queue requests on the channels. */ -const channelsRunning: DiscordApi.Collection = new DiscordApi.Collection(); +const channelsRunning: DiscordApi.Collection = new DiscordApi.Collection(); /** * Gets the user that requested the execution * @param request The request to get the user from * @returns the user or guild member */ -export function getAuthor(request: DiscordApi.Message | DiscordApi.Interaction) { - if (request instanceof DiscordApi.Message) return request.member ?? request.author; +export function getAuthor(request: apiRequest) { + if (request instanceof DiscordApi.Message) return request.author; return request.user; } @@ -54,9 +58,11 @@ async function getUserLimit(user: string | {id: string}, requestTimestamp: Date) * Check and queues up the request and runs it if there is nothing in queue. * @param request the message to check and queue */ -export async function queueRequest(request: DiscordApi.Message | DiscordApi.Interaction) { +export async function queueRequest(request: apiRequest) { if (!request.channelId) { - if (!(request instanceof DiscordApi.Message) && request.isRepliable()) + if (request instanceof DiscordApi.Message) + request.reply("request does not have channelId"); + else if (request.isRepliable()) request.reply("request does not have channelId"); console.log("There was incoming execution without channelId set, ignoring"); console.log(request); @@ -90,7 +96,7 @@ export async function queueRequest(request: DiscordApi.Message | DiscordApi.Inte () => { return []; }, ); const shouldStart = messagesForChannel.length == 0; - messagesForChannel.push(request); + messagesForChannel.push(request as request); if (shouldStart) executeFromQueue(request.channelId); } @@ -100,8 +106,8 @@ export async function queueRequest(request: DiscordApi.Message | DiscordApi.Inte * @param channel the channel to run the queue for */ async function executeFromQueue(channel: string) { - const channelQueue = channelsRunning.get(channel) as DiscordApi.Message[]; - const message = channelQueue.at(0) as DiscordApi.Message; + const channelQueue = channelsRunning.get(channel) as NonNullable>; + const message = channelQueue.at(0) as NonNullable>; try { let messages: DiscordApi.Collection = await message.channel.messages.fetch({ limit: config.limits.messages, cache: false }); @@ -110,7 +116,13 @@ async function executeFromQueue(channel: string) { messages.forEach(m => Moderation.checkMessage(m)); - message.channel.sendTyping(); + if (message instanceof DiscordApi.Message) { + message.channel.sendTyping(); + } + else if (message.isRepliable()) { + message.deferReply(); + } + const answer = await openai.createChatCompletion({ ...config.chatCompletionConfig, messages: toOpenAIMessages(messages), @@ -118,13 +130,13 @@ async function executeFromQueue(channel: string) { const usage = answer.data.usage; if (usage != undefined) { - const channelName: string = message.inGuild() ? `${message.channel.name} (${message.guild.name})` : `@${message.author.tag}`; - console.log(`Used ${usage.total_tokens} (${usage.prompt_tokens} + ${usage.completion_tokens}) tokens for ${message.author.tag} (${message.author.id}) in #${channelName}`); + const channelName: string = !message.channel.isDMBased() ? `${message.channel.name} (${message.guild?.name})` : `@${getAuthor(message).tag}`; + console.log(`Used ${usage.total_tokens} (${usage.prompt_tokens} + ${usage.completion_tokens}) tokens for ${getAuthor(message).tag} (${getAuthor(message).id}) in #${channelName}`); database.usage.create({ data: { timestamp: message.createdAt, - user: BigInt(message.author.id), + user: BigInt(getAuthor(message).id), channel: BigInt(message.channelId), guild: message.guildId ? BigInt(message.guildId) : null, usageReguest: usage.prompt_tokens, @@ -149,7 +161,7 @@ async function executeFromQueue(channel: string) { Moderation.checkMessage(await response); } else { - message.react("😶"); + if (message instanceof DiscordApi.Message) message.react("😶"); } } catch (e) { console.error(`Error ocurred while handling chat completion request (${(e as object).constructor.name}):`);