diff --git a/src/execution.ts b/src/execution.ts index 38699eb..be0156b 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -1,4 +1,4 @@ -import DiscordApi, { GuildTextBasedChannel } from "discord.js"; +import DiscordApi, { GuildTextBasedChannel, TextBasedChannel } from "discord.js"; import { ChatCompletionRequestMessage, ChatCompletionResponseMessage } from "openai"; import Axios from "axios"; @@ -14,6 +14,33 @@ export type RequestMessage = apiRequest & NonNullableInObject { tries = 0; + channel: TextBasedChannel; + + private typingWorker = setInterval(() => this.sendTyping(), 5000).unref(); + + private typingStopper = setTimeout(() => this.stopTyping(), 60000).unref(); + + constructor(channel: TextBasedChannel) { + super(); + this.channel = channel; + clearInterval(this.typingStopper); + clearTimeout(this.typingStopper); + } + + startTyping() { + this.sendTyping(); + this.typingWorker.refresh(); + this.typingStopper.refresh(); + } + + stopTyping() { + clearInterval(this.typingWorker); + clearTimeout(this.typingStopper); + } + + sendTyping() { + this.channel.sendTyping().catch(() => {/* GRACEFAIL: we fail to send the typing then */}); + } shift() { this.tries = 0; @@ -177,7 +204,7 @@ export async function queueRequest(request: apiRequest) { const messagesForChannel = channelsRunning.ensure( request.channelId, - () => { return new ChannelsRunningValue; }, + () => { return new ChannelsRunningValue(request.channel as TextBasedChannel); }, ); const shouldStart = messagesForChannel.length === 0; messagesForChannel.push(request as RequestMessage); @@ -241,7 +268,7 @@ async function executeFromQueue(channel: string) { messages.forEach(m => { Moderation.checkMessageNoReturn(m); }); if (message instanceof DiscordApi.Message) { - await message.channel.sendTyping(); + channelQueue.startTyping(); } else if (message.isRepliable()) { await message.deferReply(); @@ -274,6 +301,8 @@ async function executeFromQueue(channel: string) { } } while (generatedMessage.function_call); + channelQueue.stopTyping(); + const answerContent = answer.data.choices[0].message?.content; if (answerContent === undefined || answerContent === "") { @@ -297,6 +326,7 @@ async function executeFromQueue(channel: string) { } } } catch (e) { + channelQueue.stopTyping(); console.error(`Error ocurred while handling chat completion request (${(e as object).constructor.name}):`); console.error(e); if (OpenAImessages.length !== 0) {