import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; import 'dotenv/config'; import fs = require('node:fs'); import path = require('node:path'); import { globSync } from 'glob'; const syspromptCache = path.resolve(__dirname, 'sysprompt_cache'); let sysprompt = fs.readFileSync(path.resolve(syspromptCache, 'default.txt'), 'utf-8'); function removeTrailingNewlines(sysprompt: string) { // remove trailing '\n' or '\r\n' that editors like to insert if (sysprompt[sysprompt.length - 1] == '\n') { if (sysprompt[sysprompt.length - 2] == '\r') { return sysprompt.slice(0, sysprompt.length - 2); } return sysprompt.slice(0, sysprompt.length - 1); } return sysprompt; } function getSysPrompts() { const absolutePaths = globSync(path.resolve(syspromptCache, '*.txt')); const prompts = {}; for (const filepath of absolutePaths) { const promptName = path.basename(filepath, '.txt'); const promptContents = removeTrailingNewlines(fs.readFileSync(filepath, 'utf-8')); prompts[promptName] = promptContents; } return prompts; } async function syspromptCommand(interaction: ChatInputCommandInteraction) { if (interaction.user.id !== process.env.ADMIN) { await interaction.reply("You are not authorized to change model settings"); return; } const promptDict = getSysPrompts(); const chosenPrompt = interaction.options.getString('name', true); if (Object.keys(promptDict).includes(chosenPrompt)) { sysprompt = promptDict[chosenPrompt]; } const preview = sysprompt.length > 1000 ? sysprompt.slice(0, 1000) + '\n... (truncated)' : sysprompt; await interaction.reply(`\`\`\` sysprompt = ${preview} \`\`\``); } export = { data: new SlashCommandBuilder() .setName('sysprompt') .setDescription('Set the system prompt being used') .addStringOption( opt => opt.setName('name').setDescription('Name of system prompt').setRequired(true) ), execute: syspromptCommand, state: () => removeTrailingNewlines(sysprompt) };