commands/ask: create

Allows to interact with the bot when bot is user installed in discord.
This commit is contained in:
Wroclaw 2024-04-26 05:41:07 +02:00
parent 9f5dfefb31
commit 6efb6e5876
3 changed files with 77 additions and 3 deletions

74
src/commands/ask.ts Normal file
View file

@ -0,0 +1,74 @@
import {
APIApplicationCommandOption
, ApplicationCommandOptionType
, ApplicationCommandType
, ChatInputCommandInteraction
} from "discord.js";
import { ChatCompletionMessageParam } from "openai/resources";
import
Command
,{ApplicationIntegrationType
, InteractionContextTypes
} from "../command";
import { config } from "../index";
import { executeChatCompletion, replyInMultiMessage } from "../execution";
import { formatName } from "../toOpenAIMessages";
export default class Ask extends Command implements Command {
name = "ask";
description = "Promts the bot to reply to a single message without any history context";
type = ApplicationCommandType.ChatInput;
options: APIApplicationCommandOption[] = [
{
name: "content",
description: "The content of the prompt",
type: ApplicationCommandOptionType.String,
required: true,
},
{
name: "ephemeral",
description: "if true, only you can see the response (default true)",
type: ApplicationCommandOptionType.Boolean,
required: false,
}
];
integration_types = [
ApplicationIntegrationType.Guild_Install,
ApplicationIntegrationType.User_Install,
];
contexts = [
InteractionContextTypes.Guild,
InteractionContextTypes.BotDM,
InteractionContextTypes.PrivateChannel,
];
async execute(interaction: ChatInputCommandInteraction) {
const content = interaction.options.getString("content", true);
const ephemeral = interaction.options.getBoolean("ephemeral", false) ?? true;
if (!interaction.channel && !interaction.channelId) {
console.error("No channel found in interaction");
console.error(interaction);
await interaction.reply({
content: "No channel found in interaction???",
ephemeral: true
});
return;
}
// TODO: check content in moderation API
const messages: ChatCompletionMessageParam[] = [
...config.systemPrompt(interaction),
{ role: "user", name: formatName(interaction.user.displayName), content }
];
const [answer] = await Promise.all([
executeChatCompletion(messages, interaction),
interaction.deferReply({ ephemeral }),
]);
await replyInMultiMessage(answer.choices[0].message.content, interaction);
}
}

View file

@ -315,7 +315,7 @@ async function executeFromQueue(channel: string) {
* @param answerContent - The content of the answer. * @param answerContent - The content of the answer.
* @param message - The request message to reply to. * @param message - The request message to reply to.
*/ */
async function replyInMultiMessage(answerContent: string | null, message: apiRequest) { export async function replyInMultiMessage(answerContent: string | null, message: apiRequest) {
if (answerContent === null || answerContent === "") { if (answerContent === null || answerContent === "") {
if (message instanceof DiscordApi.Message) message.react("😶").catch(() => { }); if (message instanceof DiscordApi.Message) message.react("😶").catch(() => { });
} }
@ -345,7 +345,7 @@ async function replyInMultiMessage(answerContent: string | null, message: apiReq
* @param message An optional RequestMessage object representing the request message, used for logging. * @param message An optional RequestMessage object representing the request message, used for logging.
* @returns A Promise that resolves to the answer from the chat completion process. * @returns A Promise that resolves to the answer from the chat completion process.
*/ */
async function executeChatCompletion( export async function executeChatCompletion(
OpenAImessages: ChatCompletionMessageParam[], OpenAImessages: ChatCompletionMessageParam[],
message: apiRequest | undefined, message: apiRequest | undefined,
) { ) {

View file

@ -63,7 +63,7 @@ export function formatMessage(message: DiscordMessage): string {
* @param name the name to format * @param name the name to format
* @returns formatted name * @returns formatted name
*/ */
function formatName(name: string): string { export function formatName(name: string): string {
// replace all characters to ascii equivelant // replace all characters to ascii equivelant
return FoldToAscii.foldReplacing(name) return FoldToAscii.foldReplacing(name)
// White spaces are not allowed // White spaces are not allowed