From 18646b9dc6a37b7ee2594cd6d5352930461e4f9f Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Thu, 21 Sep 2023 20:43:43 +0200 Subject: [PATCH 01/39] config: fix imports not working correctly this patch moves the rootDir of the typescript project up a directory this moves all content in the dist directory inside the new src directory I couldn't find other way --- Dockerfile | 2 +- package.json | 6 +++--- src/index.ts | 12 ++++++++++-- tsconfig.json | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index d288a6a..4b9f015 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ COPY src ./src RUN npx tsc # Run the app -CMD ["node", "dist/index.js"] +CMD ["node", "dist/src/index.js"] diff --git a/package.json b/package.json index 27b96fb..16a5e24 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,11 @@ "name": "gptcord", "version": "0.1.0", "description": "", - "main": "./dist/index.js", + "main": "./dist/src/index.js", "scripts": { - "start": "tsc && node dist/index.js", + "start": "tsc && node dist/src/index.js", "test": "echo \"Error: no test specified\" && exit 1", - "publishCommands": "tsc && node dist/scripts/pushCommands.js" + "publishCommands": "tsc && node dist/src/scripts/pushCommands.js" }, "author": "Wroclaw", "license": "MIT", diff --git a/src/index.ts b/src/index.ts index ac2a2a7..66a2ceb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,9 +23,17 @@ function getConfig() { ["./config.ts"], {outDir: "./dist"} ); - program.emit(program.getSourceFile("./config.ts")); + + program.getSourceFiles() + .filter(e => { + if (!e.fileName.match(`^${process.cwd()}`)) return true; + if (e.fileName.match(`${process.cwd()}/node_modules`)) return false; + if (e.fileName.match(`${process.cwd()}/src/`)) return false; + return true; + }) + .forEach(e => program.emit(e)); // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access - fileConfig = require("./config").default as IConfig; + fileConfig = require("../config").default as IConfig; } catch (e) { //FIXME: make errors more descriptive to the enduser console.log(e); diff --git a/tsconfig.json b/tsconfig.json index 66df360..77c5666 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "module": "CommonJS", "sourceMap": true, "outDir": "./dist/", - "rootDir": "./src/", + "rootDir": "./", "strict": true, "moduleResolution": "node", "esModuleInterop": true, From 2629659ffc64d78ff2506cea7a70f0c50aed7ff4 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Thu, 21 Sep 2023 20:57:40 +0200 Subject: [PATCH 02/39] Interactions: fix on failed reply to be ephemeral fixes #17 --- src/interactionManager.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/interactionManager.ts b/src/interactionManager.ts index ff1614b..c80b32d 100644 --- a/src/interactionManager.ts +++ b/src/interactionManager.ts @@ -34,8 +34,9 @@ export default class CommandManager { interaction.reply({ embeds: [{ color: 0xff0000, - description: `Failed to perform interaction:\n\`${e}\``, - }] + description: `Failed to perform interaction:\n\`\`${e}\`\``, + }], + ephemeral: true, }).catch(() => {/* NOTE: We're still logging the issue that happened to the console */}); console.error(`Failed to perform interaction: ${interaction.commandName}`); console.error(e); From 94992743e86dd8f4eabe22e77dca532f989d2dd6 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Thu, 21 Sep 2023 21:51:03 +0200 Subject: [PATCH 03/39] quota/tokenCount: fix "null from a database" --- src/quota/tokenCount.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/quota/tokenCount.ts b/src/quota/tokenCount.ts index 263ba13..47e9e99 100644 --- a/src/quota/tokenCount.ts +++ b/src/quota/tokenCount.ts @@ -51,12 +51,13 @@ export default class tokenCount implements IQuota { } }))._sum; - if (!usedTokens.usageRequest || !usedTokens.usageResponse) throw new Error("Null from a database!! (tokenCount Quota)"); + const usageRequest = usedTokens.usageRequest === null ? 0 : usedTokens.usageRequest; + const usageResponse = usedTokens.usageResponse === null ? 0 : usedTokens.usageResponse; const usedUnits = (() => { if (this.considerInputTokensAsHalf) - return usedTokens.usageResponse + usedTokens.usageRequest / 2; - return usedTokens.usageResponse + usedTokens.usageRequest; + return usageResponse + usageRequest / 2; + return usageResponse + usageRequest; })(); if (userQuota?.vip) return this.createUserQuotaData(Infinity, usedUnits); From 552143e3458bdbd0890fb95a4f38c73bf4e9b22d Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Mon, 25 Sep 2023 09:30:52 +0200 Subject: [PATCH 04/39] quota/tokenCount: Rename single variable name to something that has more sense I forgot to rename it when I commited it last time ;-; --- src/quota/tokenCount.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quota/tokenCount.ts b/src/quota/tokenCount.ts index 47e9e99..4c24fbb 100644 --- a/src/quota/tokenCount.ts +++ b/src/quota/tokenCount.ts @@ -121,14 +121,14 @@ export default class tokenCount implements IQuota { ): Promise { const userId = typeof user ==="string" ? user : user.id; - const [userQuota, renameMebecause] = await Promise.all([ + const [userQuota, overUnitCountRecord] = await Promise.all([ this.checkUser(userId, request), this.findNthUsage(userId, request.createdTimestamp, unitCount) ]); return { ...userQuota, - recoveryTimestamp: (renameMebecause.at(0)?.timestamp.valueOf() ?? Infinity) + this.lookback, + recoveryTimestamp: (overUnitCountRecord.at(0)?.timestamp.valueOf() ?? Infinity) + this.lookback, }; } From 80f4f18eabc7f88b8e9537c4cba21b4024ca182d Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Mon, 25 Sep 2023 09:52:22 +0200 Subject: [PATCH 05/39] quota/tokenCount: allow arbitrary multipliers for tokens I didn't notice that OpenAI changed pricing again --- src/quota/tokenCount.ts | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/quota/tokenCount.ts b/src/quota/tokenCount.ts index 4c24fbb..1756c85 100644 --- a/src/quota/tokenCount.ts +++ b/src/quota/tokenCount.ts @@ -12,16 +12,19 @@ import { Usage } from "@prisma/client"; export default class tokenCount implements IQuota { defaultQuota: number; lookback: number; - considerInputTokensAsHalf: boolean; + requestTokenMultiplier: number; + responseTokenMultiplier: number; constructor( defaultQuota: number = 512 * 25, lookback: number = 1000 * 60 * 60 * 24, - considerInputTokensAsHalf: boolean = true, + requestTokenMultiplier: number = 1, + responseTokenMultiplier: number = 1, ) { this.defaultQuota = defaultQuota; this.lookback = lookback; - this.considerInputTokensAsHalf = considerInputTokensAsHalf; + this.requestTokenMultiplier = requestTokenMultiplier; + this.responseTokenMultiplier = responseTokenMultiplier; } private getUserQuota(id: string) { @@ -55,9 +58,7 @@ export default class tokenCount implements IQuota { const usageResponse = usedTokens.usageResponse === null ? 0 : usedTokens.usageResponse; const usedUnits = (() => { - if (this.considerInputTokensAsHalf) - return usageResponse + usageRequest / 2; - return usageResponse + usageRequest; + return usageRequest * this.requestTokenMultiplier + usageResponse * this.responseTokenMultiplier; })(); if (userQuota?.vip) return this.createUserQuotaData(Infinity, usedUnits); @@ -74,30 +75,13 @@ export default class tokenCount implements IQuota { * @returns promise of giving out the record */ findNthUsage(user: string, requestTimestamp: number, unitCount: number) { - if (this.considerInputTokensAsHalf) - return database.$queryRaw>` - SELECT t1.*, ( - SELECT - SUM(usageResponse + usageRequest/2) AS usage - FROM \`usage\` - WHERE - user = ${user} AND - timestamp >= ${requestTimestamp - this.lookback} AND - timestamp <= t1.timestamp - ) as usage - FROM - \`usage\` AS t1 - WHERE - user = ${user} AND - timestamp >= ${requestTimestamp - this.lookback} AND - usage >= ${unitCount} - ORDER BY timestamp ASC - LIMIT 1 - `; - return database.$queryRaw>` + return database.$queryRaw>` SELECT t1.*, ( SELECT - SUM(usageResponse + usageRequest) AS usage + SUM( + usageRequest * ${this.requestTokenMultiplier} + + usageResponse * ${this.responseTokenMultiplier} + ) AS usage FROM \`usage\` WHERE user = ${user} AND From 49b074f98e3f6276f0d2fc00510687cd25dab51f Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Mon, 25 Sep 2023 11:10:21 +0200 Subject: [PATCH 06/39] /check-limit: show when the user can use the bot again by default fixes #12 --- src/commands/check-limit.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/commands/check-limit.ts b/src/commands/check-limit.ts index c9e667b..834a8e0 100644 --- a/src/commands/check-limit.ts +++ b/src/commands/check-limit.ts @@ -22,9 +22,20 @@ export default class MyLimit extends Command implements Command { ]; async execute(interaction: ChatInputCommandInteraction) { - let recoveryFor = interaction.options.getInteger("recovery-for", false) ?? 1; + let recoveryFor = interaction.options.getInteger("recovery-for", false); const ephemeral = interaction.options.getBoolean("ephemeral", false) ?? true; + if (recoveryFor === null) { + const userQuota = await config.quota.checkUser( + interaction.user, + interaction, + ); + const remaining = userQuota.quota - userQuota.used; + // NOTE: In order for user to execute the bot again, the used must be lower than quota + // user can't execute if quota and used are equal + // thus why we add 1 here + recoveryFor = remaining >= 0 ? 1 : 1 - remaining; + } if (recoveryFor <= 0) recoveryFor = 1; const userQuotaRecovery = await config.quota.getUserQuotaRecovery(interaction.user, interaction, recoveryFor); From 6272c7f551a3720fcec9ddc90d790d34a27dbe1d Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Mon, 25 Sep 2023 11:32:52 +0200 Subject: [PATCH 07/39] /check-limit: change description of recovery-for paramteter to mach it better for the current default behaviour --- src/commands/check-limit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/check-limit.ts b/src/commands/check-limit.ts index 834a8e0..28ccd6e 100644 --- a/src/commands/check-limit.ts +++ b/src/commands/check-limit.ts @@ -10,7 +10,7 @@ export default class MyLimit extends Command implements Command { options: ApplicationCommandOption[] = [ { name: "recovery-for", - description: "Calculate the limit recovery time for given message count (default 1)", + description: "Calculate the limit recovery time for given message count (default: amount required to use the bot again or 1)", type: ApplicationCommandOptionType.Integer, required: false, }, From 03a1c62cd5fa745058559adb505036740bf86f2f Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 26 Sep 2023 18:17:12 +0200 Subject: [PATCH 08/39] Execution: Stringify response error on axios error I'm sick of not understanding the 400 problem --- src/execution.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/execution.ts b/src/execution.ts index aa99e73..0fbe1d2 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -287,7 +287,12 @@ 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 (Axios.isAxiosError(e)) { + console.error(JSON.stringify(e.response?.data)); + } + else { + console.error(e); + } if (OpenAImessages.length !== 0) { console.error("Messages:"); console.error(OpenAImessages); From 8ed2e758f8293d3ff0c9fb063f1de7b6b7039a9c Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 27 Sep 2023 15:52:30 +0200 Subject: [PATCH 09/39] Update dependencies OpenAI package will be updated soon, as it needs codebase migration --- package-lock.json | 536 ++++++++++++++---------------------- package.json | 6 +- src/command.ts | 4 +- src/commands/check-limit.ts | 4 +- 4 files changed, 211 insertions(+), 339 deletions(-) diff --git a/package-lock.json b/package-lock.json index 295d810..9197f43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gptcord", - "version": "0.0.2", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gptcord", - "version": "0.0.2", + "version": "0.1.0", "license": "MIT", "dependencies": { "@prisma/client": "^5.0.0", @@ -36,84 +36,85 @@ } }, "node_modules/@discordjs/builders": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.3.tgz", - "integrity": "sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.5.tgz", + "integrity": "sha512-SdweyCs/+mHj+PNhGLLle7RrRFX9ZAhzynHahMCLqp5Zeq7np7XC6/mgzHc79QoVlQ1zZtOkTTiJpOZu5V8Ufg==", "dependencies": { - "@discordjs/formatters": "^0.3.1", - "@discordjs/util": "^0.3.1", - "@sapphire/shapeshift": "^3.8.2", - "discord-api-types": "^0.37.41", + "@discordjs/formatters": "^0.3.2", + "@discordjs/util": "^1.0.1", + "@sapphire/shapeshift": "^3.9.2", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.3", - "tslib": "^2.5.0" + "tslib": "^2.6.1" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/collection": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.1.tgz", - "integrity": "sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/formatters": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz", - "integrity": "sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.2.tgz", + "integrity": "sha512-lE++JZK8LSSDRM5nLjhuvWhGuKiXqu+JZ/DsOR89DVVia3z9fdCJVcHF2W/1Zxgq0re7kCzmAJlCMMX3tetKpA==", "dependencies": { - "discord-api-types": "^0.37.41" + "discord-api-types": "0.37.50" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/rest": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz", - "integrity": "sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.1.tgz", + "integrity": "sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==", "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/util": "^0.3.0", + "@discordjs/collection": "^1.5.3", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.4.2", - "discord-api-types": "^0.37.41", - "file-type": "^18.3.0", - "tslib": "^2.5.0", - "undici": "^5.22.0" + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "magic-bytes.js": "^1.0.15", + "tslib": "^2.6.1", + "undici": "5.22.1" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/util": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz", - "integrity": "sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.1.tgz", + "integrity": "sha512-d0N2yCxB8r4bn00/hvFZwM7goDcUhtViC5un4hPj73Ba4yrChLSJD8fy7Ps5jpTLg1fE9n4K0xBLc1y9WGwSsA==", "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/ws": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-0.8.3.tgz", - "integrity": "sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.1.tgz", + "integrity": "sha512-avvAolBqN3yrSvdBPcJ/0j2g42ABzrv3PEL76e3YTp2WYMGH7cuspkjfSyNWaqYl1J+669dlLp+YFMxSVQyS5g==", "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", + "@discordjs/collection": "^1.5.3", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.4", - "@vladfrangu/async_event_emitter": "^2.2.1", - "discord-api-types": "^0.37.41", - "tslib": "^2.5.0", + "@types/ws": "^8.5.5", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "tslib": "^2.6.1", "ws": "^8.13.0" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -132,18 +133,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.0.tgz", + "integrity": "sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -164,18 +165,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", - "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -241,12 +242,12 @@ } }, "node_modules/@prisma/client": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.0.0.tgz", - "integrity": "sha512-XlO5ELNAQ7rV4cXIDJUNBEgdLwX3pjtt9Q/RHqDpGf43szpNJx2hJnggfFs7TKNx0cOFsl6KJCSfqr5duEU/bQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", + "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584" + "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" }, "engines": { "node": ">=16.13" @@ -261,16 +262,16 @@ } }, "node_modules/@prisma/engines": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz", - "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", + "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584.tgz", - "integrity": "sha512-HHiUF6NixsldsP3JROq07TYBLEjXFKr6PdH8H4gK/XAoTmIplOJBCgrIUMrsRAnEuGyRoRLXKXWUb943+PFoKQ==" + "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", + "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" }, "node_modules/@sapphire/async-queue": { "version": "1.5.0", @@ -303,11 +304,6 @@ "npm": ">=7.0.0" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, "node_modules/@types/fold-to-ascii": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/fold-to-ascii/-/fold-to-ascii-5.0.0.tgz", @@ -315,55 +311,54 @@ "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", "dev": true }, "node_modules/@types/node": { - "version": "20.4.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.4.tgz", - "integrity": "sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew==" + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" }, "node_modules/@types/require-directory": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/require-directory/-/require-directory-2.1.2.tgz", - "integrity": "sha512-FUG5PJ2rsV2TssSspVZefTR8+wH3Ahr6KdAB6WanLNroSDu0A5ew4WVUxnnGU/E1k6nzip9ZawGAAe/ZqzGn5g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/require-directory/-/require-directory-2.1.3.tgz", + "integrity": "sha512-B4uMLVwf83xg/o6RsEX8ifMDHyBgNhwU0JCpveJeT1DLoIDjgHjNH3ZDcPoyoJVAfa++wJfhiFPG3B/ztwhVww==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", "dev": true }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.6.tgz", + "integrity": "sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", - "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", + "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/type-utils": "6.2.0", - "@typescript-eslint/utils": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/type-utils": "6.7.3", + "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", - "natural-compare-lite": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -385,15 +380,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", - "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", + "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4" }, "engines": { @@ -413,13 +408,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", - "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", + "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0" + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -430,13 +425,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", - "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", + "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.2.0", - "@typescript-eslint/utils": "6.2.0", + "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/utils": "6.7.3", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -457,9 +452,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", - "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", + "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -470,13 +465,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", - "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", + "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/visitor-keys": "6.2.0", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/visitor-keys": "6.7.3", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -497,17 +492,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", - "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", + "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.0", - "@typescript-eslint/types": "6.2.0", - "@typescript-eslint/typescript-estree": "6.2.0", + "@typescript-eslint/scope-manager": "6.7.3", + "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/typescript-estree": "6.7.3", "semver": "^7.5.4" }, "engines": { @@ -522,12 +517,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", - "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", + "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/types": "6.7.3", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -798,27 +793,27 @@ "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" }, "node_modules/discord.js": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.11.0.tgz", - "integrity": "sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.13.0.tgz", + "integrity": "sha512-Kufdvg7fpyTEwANGy9x7i4od4yu5c6gVddGi5CKm4Y5a6sF0VBODObI3o0Bh7TGCj0LfNT8Qp8z04wnLFzgnbA==", "dependencies": { - "@discordjs/builders": "^1.6.3", - "@discordjs/collection": "^1.5.1", - "@discordjs/formatters": "^0.3.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", - "@discordjs/ws": "^0.8.3", - "@sapphire/snowflake": "^3.4.2", - "@types/ws": "^8.5.4", - "discord-api-types": "^0.37.41", + "@discordjs/builders": "^1.6.5", + "@discordjs/collection": "^1.5.3", + "@discordjs/formatters": "^0.3.2", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", + "@discordjs/ws": "^1.0.1", + "@sapphire/snowflake": "^3.5.1", + "@types/ws": "^8.5.5", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.5.0", - "undici": "^5.22.0", + "tslib": "^2.6.1", + "undici": "5.22.1", "ws": "^8.13.0" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/doctrine": { @@ -846,16 +841,16 @@ } }, "node_modules/eslint": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", - "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.1", - "@eslint/js": "^8.46.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.50.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", @@ -865,7 +860,7 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.2", + "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", @@ -916,9 +911,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", - "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1052,22 +1047,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-type": { - "version": "18.5.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.5.0.tgz", - "integrity": "sha512-yvpl5U868+V6PqXHMmsESpg6unQ5GfnPssl4dxdJudBrr9qy7Fddt7EVX1VLlddFfe8Gj9N7goCZH22FXuSQXQ==", - "dependencies": { - "readable-web-to-node-stream": "^3.0.2", - "strtok3": "^7.0.0", - "token-types": "^5.0.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1097,22 +1076,23 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.7", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/fold-to-ascii": { @@ -1124,9 +1104,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "funding": [ { "type": "individual", @@ -1194,9 +1174,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1248,25 +1228,6 @@ "node": ">=8" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1314,7 +1275,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-extglob": { "version": "2.1.1", @@ -1373,6 +1335,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1385,6 +1353,15 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -1441,6 +1418,11 @@ "node": ">=10" } }, + "node_modules/magic-bytes.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.2.0.tgz", + "integrity": "sha512-NFrX8tqiYYrIiMQ3f0UkqG8INKzF8Lz7Jo2c5Ut6b5/Bzp/sr2z6dQoXPSLVDaioM2N6/k+3sDnD/y4Xpx6lSQ==" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1506,12 +1488,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1625,18 +1601,6 @@ "node": ">=8" } }, - "node_modules/peek-readable": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", - "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1659,13 +1623,13 @@ } }, "node_modules/prisma": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz", - "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", + "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.0.0" + "@prisma/engines": "5.3.1" }, "bin": { "prisma": "build/index.js" @@ -1703,34 +1667,6 @@ } ] }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1796,25 +1732,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -1868,14 +1785,6 @@ "node": ">=10.0.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1900,22 +1809,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strtok3": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", - "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1946,26 +1839,10 @@ "node": ">=8.0" } }, - "node_modules/token-types": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", "dev": true, "engines": { "node": ">=16.13.0" @@ -1980,9 +1857,9 @@ "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" }, "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/type-check": { "version": "0.4.0", @@ -2009,9 +1886,9 @@ } }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -2041,11 +1918,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2068,9 +1940,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 16a5e24..2d3203c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", "openai": "^3.2.1", - "require-directory": "^2.1.1" + "require-directory": "^2.1.1", + "typescript": "^5.1.6" }, "devDependencies": { "@types/fold-to-ascii": "^5.0.0", @@ -24,7 +25,6 @@ "@typescript-eslint/eslint-plugin": "^6.2.0", "@typescript-eslint/parser": "^6.2.0", "eslint": "^8.46.0", - "prisma": "^5.0.0", - "typescript": "^5.1.6" + "prisma": "^5.0.0" } } diff --git a/src/command.ts b/src/command.ts index 2334ad0..d053e72 100644 --- a/src/command.ts +++ b/src/command.ts @@ -1,6 +1,6 @@ import { AutocompleteInteraction, PermissionsBitField } from "discord.js"; import { RESTPostAPIApplicationCommandsJSONBody } from "discord.js"; -import { ApplicationCommandOption, ApplicationCommandType, ChatInputCommandInteraction, LocalizationMap, MessageInteraction, PermissionResolvable, UserSelectMenuInteraction } from "discord.js"; +import { APIApplicationCommandOption, ApplicationCommandType, ChatInputCommandInteraction, LocalizationMap, MessageInteraction, PermissionResolvable, UserSelectMenuInteraction } from "discord.js"; type InteractionTypeMap = { [ApplicationCommandType.ChatInput]: [ChatInputCommandInteraction, string]; @@ -13,7 +13,7 @@ interface Command Date: Wed, 27 Sep 2023 17:14:17 +0200 Subject: [PATCH 10/39] Update OpenAI dependency --- package-lock.json | 236 +++++++++++++++++++++++++++++++++------- package.json | 2 +- src/configDefault.ts | 6 +- src/execution.ts | 68 +++++++----- src/funcitonManager.ts | 7 +- src/index.ts | 6 +- src/moderation.ts | 4 +- src/toOpenAIMessages.ts | 2 +- 8 files changed, 250 insertions(+), 81 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9197f43..b20e096 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,9 @@ "discord.js": "^14.8.0", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", - "openai": "^3.2.1", - "require-directory": "^2.1.1" + "openai": "^4.10.0", + "require-directory": "^2.1.1", + "typescript": "^5.1.6" }, "devDependencies": { "@types/fold-to-ascii": "^5.0.0", @@ -22,8 +23,7 @@ "@typescript-eslint/eslint-plugin": "^6.2.0", "@typescript-eslint/parser": "^6.2.0", "eslint": "^8.46.0", - "prisma": "^5.0.0", - "typescript": "^5.1.6" + "prisma": "^5.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -321,6 +321,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" }, + "node_modules/@types/node-fetch": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/require-directory": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@types/require-directory/-/require-directory-2.1.3.tgz", @@ -542,6 +551,17 @@ "npm": ">=7.0.0" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -563,6 +583,17 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -623,20 +654,17 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -695,6 +723,14 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -744,6 +780,14 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -775,6 +819,15 @@ "node": ">=0.4.0" } }, + "node_modules/digest-fetch": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", + "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", + "dependencies": { + "base-64": "^0.1.0", + "md5": "^2.3.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -981,6 +1034,14 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1103,25 +1164,6 @@ "node": ">= 6.3.1" } }, - "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -1135,6 +1177,23 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1228,6 +1287,14 @@ "node": ">=8" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1278,6 +1345,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1423,6 +1495,16 @@ "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.2.0.tgz", "integrity": "sha512-NFrX8tqiYYrIiMQ3f0UkqG8INKzF8Lz7Jo2c5Ut6b5/Bzp/sr2z6dQoXPSLVDaioM2N6/k+3sDnD/y4Xpx6lSQ==" }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1479,8 +1561,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -1488,6 +1569,43 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1498,14 +1616,28 @@ } }, "node_modules/openai": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-3.3.0.tgz", - "integrity": "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.10.0.tgz", + "integrity": "sha512-II4b5/7qzwYkqA9MSjgqdofCc798EW+dtF2h6qNaVLet+qO7FShAJTWnoyzb50J4ZH1rPxRFAsmDLIhY3PT6DQ==", "dependencies": { - "axios": "^0.26.0", - "form-data": "^4.0.0" + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "digest-fetch": "^1.3.0", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" } }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.18.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.0.tgz", + "integrity": "sha512-3xA4X31gHT1F1l38ATDIL9GpRLdwVhnEFC8Uikv5ZLlXATwrCYyPq7ZWHxzxc3J/30SUiwiYT+bQe0/XvKlWbw==" + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -1839,6 +1971,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -1889,7 +2026,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1918,6 +2054,28 @@ "punycode": "^2.1.0" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 2d3203c..feb71a3 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "discord.js": "^14.8.0", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", - "openai": "^3.2.1", + "openai": "^4.10.0", "require-directory": "^2.1.1", "typescript": "^5.1.6" }, diff --git a/src/configDefault.ts b/src/configDefault.ts index 608806b..65785a9 100644 --- a/src/configDefault.ts +++ b/src/configDefault.ts @@ -1,8 +1,8 @@ import { Message } from "discord.js"; import { - ChatCompletionRequestMessage as OpenAIMessage, - CreateChatCompletionRequest as ChatCompletionRequestData, -} from "openai"; + ChatCompletionMessageParam as OpenAIMessage, + ChatCompletionCreateParamsNonStreaming as ChatCompletionRequestData, +} from "openai/resources/chat"; import IQuota from "./IQuota"; import MessageCount from "./quota/messageCount"; diff --git a/src/execution.ts b/src/execution.ts index 0fbe1d2..7575118 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -1,11 +1,11 @@ import DiscordApi, { GuildTextBasedChannel, TextBasedChannel } from "discord.js"; -import { ChatCompletionRequestMessage, ChatCompletionResponseMessage } from "openai"; -import Axios from "axios"; +import {APIError as OpenAIError} from "openai"; import { database, openai, config } from "./index"; import Moderation from "./moderation"; import toOpenAIMessages from "./toOpenAIMessages"; import FunctionManager from "./funcitonManager"; +import { ChatCompletion, ChatCompletionMessage, ChatCompletionMessageParam } from "openai/resources/chat"; type NonNullableInObject = { [k in keyof T]: k extends V ? NonNullable : T[k] }; export type apiRequest = DiscordApi.Message | DiscordApi.RepliableInteraction; @@ -171,12 +171,12 @@ export async function queueRequest(request: apiRequest) { * @param functionRan counter of how many function have been ran */ function logUsedTokens( - answer: Awaited>, + answer: ChatCompletion, message: RequestMessage, functionRan: number, ) { - const usage = answer.data.usage; - const functionName = answer.data.choices[0].message?.function_call?.name; + const usage = answer.usage; + const functionName = answer.choices[0].message?.function_call?.name; if (usage !== undefined) { 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}${functionName ? " [Function: " + functionName + "]" : ""}`); @@ -207,7 +207,7 @@ async function executeFromQueue(channel: string) { const channelQueue = channelsRunning.get(channel) as ChannelsRunningValue; const message = channelQueue.at(0) as RequestMessage; let functionRanCounter = 0; - let OpenAImessages: ChatCompletionRequestMessage[] = []; + let OpenAImessages: ChatCompletionMessageParam[] = []; // ignore if we can't even send anything to reply if (!canReplyToRequest(message)) return; @@ -234,11 +234,11 @@ async function executeFromQueue(channel: string) { }); OpenAImessages = toOpenAIMessages(messages.values()); - let generatedMessage: ChatCompletionResponseMessage | undefined = undefined; - let answer: Awaited>; + let generatedMessage: ChatCompletionMessage | undefined = undefined; + let answer: Awaited>; do { - answer = await openai.createChatCompletion({ + answer = await openai.chat.completions.create({ ...config.chatCompletionParams, messages: OpenAImessages, // FIXME: don't use new instance of FunctionManager @@ -247,7 +247,7 @@ async function executeFromQueue(channel: string) { logUsedTokens(answer, message, ++functionRanCounter); - generatedMessage = answer.data.choices[0].message; + generatedMessage = answer.choices[0].message; if (!generatedMessage) throw new Error("Empty message received"); // handle function calls @@ -262,9 +262,9 @@ async function executeFromQueue(channel: string) { channelQueue.stopTyping(); - const answerContent = answer.data.choices[0].message?.content; + const answerContent = answer.choices[0].message?.content; - if (answerContent === undefined || answerContent === "") { + if (answerContent === null || answerContent === "") { if (message instanceof DiscordApi.Message) message.react("😶").catch(() => {/* GRACEFAIL: It's okay if the bot won't reply */}); } else { @@ -285,29 +285,37 @@ async function executeFromQueue(channel: string) { } } } catch (e) { + let errorText: string = ""; channelQueue.stopTyping(); - console.error(`Error ocurred while handling chat completion request (${(e as object).constructor.name}):`); - if (Axios.isAxiosError(e)) { - console.error(JSON.stringify(e.response?.data)); - } - else { + if (typeof e !== "object") { + console.error(`Error ocurred while handling chat completion request (${typeof e}):`); console.error(e); } - if (OpenAImessages.length !== 0) { - console.error("Messages:"); - console.error(OpenAImessages); + else if (e === null) { + console.error ("Error ocurred while handling chat completion request: null"); } + else { + console.error(`Error ocurred while handling chat completion request (${e.constructor.name}):`); + if (e instanceof OpenAIError) { + console.error(JSON.stringify(e)); + } + else { + console.error(e); + } + if (OpenAImessages.length !== 0) { + console.error("Messages:"); + console.error(OpenAImessages); + } - let errorText = "\n"; - - if (e instanceof Error) { - errorText += e.message; - } - else errorText = ""; - if (Axios.isAxiosError(e) && e.code?.match(/^5..$/) && channelQueue.tries < 3) { - channelQueue.tries++; - await new Promise(r => setTimeout(r, 2000)); // pause for 2 seconds before retrying - return executeFromQueue(channel); + if (e instanceof Error) { + errorText = e.message; + } + else errorText = ""; + if (e instanceof OpenAIError && e.code?.match(/^5..$/) && channelQueue.tries < 3) { + channelQueue.tries++; + await new Promise(r => setTimeout(r, 2000)); // pause for 2 seconds before retrying + return executeFromQueue(channel); + } } requestReply( diff --git a/src/funcitonManager.ts b/src/funcitonManager.ts index 27d3a91..9bcb0ec 100644 --- a/src/funcitonManager.ts +++ b/src/funcitonManager.ts @@ -1,4 +1,4 @@ -import { ChatCompletionFunctions, ChatCompletionRequestMessage, ChatCompletionRequestMessageFunctionCall } from "openai"; +import { ChatCompletionCreateParams, ChatCompletionMessage, ChatCompletionMessageParam } from "openai/resources/chat"; import { config } from "./index"; @@ -13,6 +13,9 @@ type OpenAIFunctionRequestData = { [name in keyof T]: T[name]; }; +type ChatCompletionFunctions = ChatCompletionCreateParams.Function; +type ChatCompletionFunctionCall = ChatCompletionMessage.FunctionCall; + /** * Represents the function that can be ran by the OpenAI model */ @@ -61,7 +64,7 @@ export default class FunctionManager { return rvalue; } - public handleFunction(request: ChatCompletionRequestMessageFunctionCall): ChatCompletionRequestMessage { + public handleFunction(request: ChatCompletionFunctionCall): ChatCompletionMessageParam { // eslint-disable-next-line @typescript-eslint/no-explicit-any let parsedArguments: any; diff --git a/src/index.ts b/src/index.ts index 66a2ceb..27e5c45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import DiscordApi from "discord.js"; -import { Configuration as OpenAIApiConfiguration, OpenAIApi } from "openai"; +import OpenAIApi from "openai"; import { PrismaClient } from "@prisma/client"; import Typescript from "typescript"; import fs from "node:fs"; @@ -43,9 +43,9 @@ function getConfig() { export const config: IConfigRequired = getConfig(); -export const openai = new OpenAIApi(new OpenAIApiConfiguration({ +export const openai = new OpenAIApi({ apiKey: config.tokens.OpenAI -})); +}); export const database = new PrismaClient(); diff --git a/src/moderation.ts b/src/moderation.ts index 9a7439b..cafaeab 100644 --- a/src/moderation.ts +++ b/src/moderation.ts @@ -28,11 +28,11 @@ export default class Moderation { } } - const answer = await openai.createModeration({ + const answer = await openai.moderations.create({ input: await formatRequestOrResponse(message), }); - const flagged = answer.data.results[0].flagged; + const flagged = answer.results[0].flagged; this.cache.set(message.id, flagged); // FIXME: These next 7 lines does not belong there and should be refactored out. if (flagged) if (message instanceof Message) { diff --git a/src/toOpenAIMessages.ts b/src/toOpenAIMessages.ts index f7ed362..3ee9ee8 100644 --- a/src/toOpenAIMessages.ts +++ b/src/toOpenAIMessages.ts @@ -1,4 +1,4 @@ -import { ChatCompletionRequestMessage as OpenAIMessage } from "openai"; +import { ChatCompletionMessageParam as OpenAIMessage } from "openai/resources/chat"; import { Collection, Message as DiscordMessage, InteractionResponse } from "discord.js"; import FoldToAscii from "fold-to-ascii"; From ffa79e798e561c0558886977140e89f3d9e0802b Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 27 Sep 2023 20:30:08 +0200 Subject: [PATCH 11/39] Fix import grouping in execution.ts I'm silly silly bad cutie that doesn't check commits when I push them --- src/execution.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/execution.ts b/src/execution.ts index 7575118..3b8e2fd 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -1,11 +1,15 @@ import DiscordApi, { GuildTextBasedChannel, TextBasedChannel } from "discord.js"; import {APIError as OpenAIError} from "openai"; +import { + ChatCompletion, + ChatCompletionMessage, + ChatCompletionMessageParam +} from "openai/resources/chat"; import { database, openai, config } from "./index"; import Moderation from "./moderation"; import toOpenAIMessages from "./toOpenAIMessages"; import FunctionManager from "./funcitonManager"; -import { ChatCompletion, ChatCompletionMessage, ChatCompletionMessageParam } from "openai/resources/chat"; type NonNullableInObject = { [k in keyof T]: k extends V ? NonNullable : T[k] }; export type apiRequest = DiscordApi.Message | DiscordApi.RepliableInteraction; From b7f6a5fe91fb4cdffe3018e1913e8d8aa9e7d4ca Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 27 Sep 2023 20:45:23 +0200 Subject: [PATCH 12/39] toOpenAIMessages: Add fallback to use user id on empty resolved name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously if someone named whose current mechanism resolved to empty string ("Джо" for example) then the openai would scream that the name does not match their server side regex. Meaning that the bot could not be used in a given channel until that person changes it's display name or it will be forgotten for the bot. --- src/toOpenAIMessages.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/toOpenAIMessages.ts b/src/toOpenAIMessages.ts index 3ee9ee8..f93d235 100644 --- a/src/toOpenAIMessages.ts +++ b/src/toOpenAIMessages.ts @@ -88,7 +88,8 @@ function getAuthorUsername(message: DiscordMessage): string | undefined { if (name.length >= 3) return name; } const name = formatName(message.author.username); - return name; + if (name.length > 0) return name; + return message.author.id; } /** From 6a31473d22c27d13c732d36f9b4a56bcb872dfe5 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Sat, 30 Sep 2023 12:31:25 +0200 Subject: [PATCH 13/39] scripts: move scripts to the project root directory I believe, that these kind of scripts should reside there instead of src directory --- Dockerfile | 1 + package.json | 2 +- {src/scripts => scripts}/pushCommands.ts | 6 +++--- tsconfig.json | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) rename {src/scripts => scripts}/pushCommands.ts (90%) diff --git a/Dockerfile b/Dockerfile index 4b9f015..9ef0693 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN npx prisma generate # Typescript compiling COPY tsconfig.json . COPY src ./src +COPY scripts ./scripts RUN npx tsc # Run the app diff --git a/package.json b/package.json index feb71a3..a3dee49 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "start": "tsc && node dist/src/index.js", "test": "echo \"Error: no test specified\" && exit 1", - "publishCommands": "tsc && node dist/src/scripts/pushCommands.js" + "publishCommands": "tsc && node dist/scripts/pushCommands.js" }, "author": "Wroclaw", "license": "MIT", diff --git a/src/scripts/pushCommands.ts b/scripts/pushCommands.ts similarity index 90% rename from src/scripts/pushCommands.ts rename to scripts/pushCommands.ts index 3f88ee5..b6419fc 100644 --- a/src/scripts/pushCommands.ts +++ b/scripts/pushCommands.ts @@ -1,15 +1,15 @@ // https://discordjs.guide/creating-your-bot/command-deployment.html#guild-commands import { REST, RESTGetAPIOAuth2CurrentApplicationResult, RESTPostAPIApplicationCommandsJSONBody, Routes } from "discord.js"; -import { config } from "../index"; +import { config } from "../src/index"; import requireDirectory from "require-directory"; -import Command from "../command"; +import Command from "../src/command"; const post: RESTPostAPIApplicationCommandsJSONBody[] = []; const guildId = process.argv.slice(2)[0]; -requireDirectory<{default: Command}, void>(module, "../commands", { +requireDirectory<{default: Command}, void>(module, "../src/commands", { visit: function (obj) { console.log(obj); // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/tsconfig.json b/tsconfig.json index 77c5666..173e3c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "include": [ - "./src/**/*" + "./src/**/*", + "./scripts/**/*" ], "compilerOptions": { "target": "ES2022", From 4729f7f56339116600469d4c681cfbb4642f610a Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Sat, 30 Sep 2023 13:23:33 +0200 Subject: [PATCH 14/39] /check-limit: rename to check-quota and change description to match it to the new reality, limits are named quotas now description of an option previously was longer than 100 characters which discord api didn't like it --- src/commands/{check-limit.ts => check-quota.ts} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename src/commands/{check-limit.ts => check-quota.ts} (91%) diff --git a/src/commands/check-limit.ts b/src/commands/check-quota.ts similarity index 91% rename from src/commands/check-limit.ts rename to src/commands/check-quota.ts index 14c0f58..3a2f5ef 100644 --- a/src/commands/check-limit.ts +++ b/src/commands/check-quota.ts @@ -4,13 +4,13 @@ import Command from "../command"; import { config } from "../index"; export default class MyLimit extends Command implements Command { - name = "check-limit"; - description = "Checks your limit and usage"; + name = "check-quota"; + description = "Checks your quota and usage"; type = ApplicationCommandType.ChatInput; options: APIApplicationCommandOption[] = [ { name: "recovery-for", - description: "Calculate the limit recovery time for given message count (default: amount required to use the bot again or 1)", + description: "Get the recovery time for given quota units count (default: until can use the bot or 1)", type: ApplicationCommandOptionType.Integer, required: false, }, @@ -18,6 +18,7 @@ export default class MyLimit extends Command implements Command { name: "ephemeral", description: "if true, only you can see the response (default true)", type: ApplicationCommandOptionType.Boolean, + required: false, } ]; From a05047ab7df11ec332505ac7ebe014349111d244 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Sat, 30 Sep 2023 14:47:10 +0200 Subject: [PATCH 15/39] script/pushCommands: make sure the script exits --- scripts/pushCommands.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/pushCommands.ts b/scripts/pushCommands.ts index b6419fc..39ad319 100644 --- a/scripts/pushCommands.ts +++ b/scripts/pushCommands.ts @@ -37,6 +37,8 @@ const rest = new REST().setToken(config.tokens.Discord); ); } console.log("Refreshed successfully"); + process.exit(0); })().catch( e => { console.error(e); + process.exit(1); }); From a186ba9e8011a24cb3a90ee0a048c2bc193812a8 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Thu, 12 Oct 2023 11:55:53 +0200 Subject: [PATCH 16/39] scripts/pushCommands: Refactor how commands are being read this should reduce errors when reading commands also this won't fail if reading one command fails --- scripts/pushCommands.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/pushCommands.ts b/scripts/pushCommands.ts index 39ad319..25ee04e 100644 --- a/scripts/pushCommands.ts +++ b/scripts/pushCommands.ts @@ -9,15 +9,21 @@ import Command from "../src/command"; const post: RESTPostAPIApplicationCommandsJSONBody[] = []; const guildId = process.argv.slice(2)[0]; -requireDirectory<{default: Command}, void>(module, "../src/commands", { - visit: function (obj) { - console.log(obj); +const importedCommands = requireDirectory(module, "../src/commands"); + +for (const obj in importedCommands) { + try { + const allExports = importedCommands[obj] as {default: unknown}; + const defaultExport = allExports.default; // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - post.push(new obj.default().toRESTPostApplicationCommands()); - }, -}); + // @ts-expect-error + const constructedExport = new defaultExport() as unknown; + if (!(constructedExport instanceof Command)) throw new Error(`${obj}'s default does not extends Command`); + post.push(constructedExport.toRESTPostApplicationCommands()); + } catch (e) { + console.error(e); + } +} const rest = new REST().setToken(config.tokens.Discord); From c911e567c669d9af0d11c031f166222923a0cdeb Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 13 Dec 2023 16:51:47 +0100 Subject: [PATCH 17/39] Update dependencies --- package-lock.json | 522 ++++++++++++++++++++++++++-------------------- package.json | 4 +- 2 files changed, 294 insertions(+), 232 deletions(-) diff --git a/package-lock.json b/package-lock.json index b20e096..f35449d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "@prisma/client": "^5.0.0", + "@prisma/client": "5.7.0", "discord.js": "^14.8.0", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", @@ -23,7 +23,7 @@ "@typescript-eslint/eslint-plugin": "^6.2.0", "@typescript-eslint/parser": "^6.2.0", "eslint": "^8.46.0", - "prisma": "^5.0.0" + "prisma": "5.7.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -36,17 +36,17 @@ } }, "node_modules/@discordjs/builders": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.5.tgz", - "integrity": "sha512-SdweyCs/+mHj+PNhGLLle7RrRFX9ZAhzynHahMCLqp5Zeq7np7XC6/mgzHc79QoVlQ1zZtOkTTiJpOZu5V8Ufg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", + "integrity": "sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==", "dependencies": { - "@discordjs/formatters": "^0.3.2", - "@discordjs/util": "^1.0.1", - "@sapphire/shapeshift": "^3.9.2", - "discord-api-types": "0.37.50", + "@discordjs/formatters": "^0.3.3", + "@discordjs/util": "^1.0.2", + "@sapphire/shapeshift": "^3.9.3", + "discord-api-types": "0.37.61", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.3", - "tslib": "^2.6.1" + "tslib": "^2.6.2" }, "engines": { "node": ">=16.11.0" @@ -61,62 +61,78 @@ } }, "node_modules/@discordjs/formatters": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.2.tgz", - "integrity": "sha512-lE++JZK8LSSDRM5nLjhuvWhGuKiXqu+JZ/DsOR89DVVia3z9fdCJVcHF2W/1Zxgq0re7kCzmAJlCMMX3tetKpA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.3.tgz", + "integrity": "sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==", "dependencies": { - "discord-api-types": "0.37.50" + "discord-api-types": "0.37.61" }, "engines": { "node": ">=16.11.0" } }, "node_modules/@discordjs/rest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.1.tgz", - "integrity": "sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.2.0.tgz", + "integrity": "sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==", "dependencies": { - "@discordjs/collection": "^1.5.3", - "@discordjs/util": "^1.0.1", + "@discordjs/collection": "^2.0.0", + "@discordjs/util": "^1.0.2", "@sapphire/async-queue": "^1.5.0", "@sapphire/snowflake": "^3.5.1", "@vladfrangu/async_event_emitter": "^2.2.2", - "discord-api-types": "0.37.50", - "magic-bytes.js": "^1.0.15", - "tslib": "^2.6.1", - "undici": "5.22.1" + "discord-api-types": "0.37.61", + "magic-bytes.js": "^1.5.0", + "tslib": "^2.6.2", + "undici": "5.27.2" }, "engines": { "node": ">=16.11.0" } }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, "node_modules/@discordjs/util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.1.tgz", - "integrity": "sha512-d0N2yCxB8r4bn00/hvFZwM7goDcUhtViC5un4hPj73Ba4yrChLSJD8fy7Ps5jpTLg1fE9n4K0xBLc1y9WGwSsA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.2.tgz", + "integrity": "sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==", "engines": { "node": ">=16.11.0" } }, "node_modules/@discordjs/ws": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.1.tgz", - "integrity": "sha512-avvAolBqN3yrSvdBPcJ/0j2g42ABzrv3PEL76e3YTp2WYMGH7cuspkjfSyNWaqYl1J+669dlLp+YFMxSVQyS5g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.2.tgz", + "integrity": "sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==", "dependencies": { - "@discordjs/collection": "^1.5.3", - "@discordjs/rest": "^2.0.1", - "@discordjs/util": "^1.0.1", + "@discordjs/collection": "^2.0.0", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.5", + "@types/ws": "^8.5.9", "@vladfrangu/async_event_emitter": "^2.2.2", - "discord-api-types": "0.37.50", - "tslib": "^2.6.1", - "ws": "^8.13.0" + "discord-api-types": "0.37.61", + "tslib": "^2.6.2", + "ws": "^8.14.2" }, "engines": { "node": ">=16.11.0" } }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.0.0.tgz", + "integrity": "sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==", + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -133,18 +149,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.0.tgz", - "integrity": "sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -165,21 +181,29 @@ } }, "node_modules/@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -201,9 +225,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -242,13 +266,10 @@ } }, "node_modules/@prisma/client": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz", - "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.7.0.tgz", + "integrity": "sha512-cZmglCrfNbYpzUtz7HscVHl38e9CrUs31nrVoGUK1nIPXGgt8hT4jj2s657UXcNdQ/jBUxDgGmHyu2Nyrq1txg==", "hasInstallScript": true, - "dependencies": { - "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59" - }, "engines": { "node": ">=16.13" }, @@ -261,31 +282,64 @@ } } }, + "node_modules/@prisma/debug": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.7.0.tgz", + "integrity": "sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA==", + "devOptional": true + }, "node_modules/@prisma/engines": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz", - "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.7.0.tgz", + "integrity": "sha512-TkOMgMm60n5YgEKPn9erIvFX2/QuWnl3GBo6yTRyZKk5O5KQertXiNnrYgSLy0SpsKmhovEPQb+D4l0SzyE7XA==", "devOptional": true, - "hasInstallScript": true + "hasInstallScript": true, + "dependencies": { + "@prisma/debug": "5.7.0", + "@prisma/engines-version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", + "@prisma/fetch-engine": "5.7.0", + "@prisma/get-platform": "5.7.0" + } }, "node_modules/@prisma/engines-version": { - "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz", - "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w==" + "version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9.tgz", + "integrity": "sha512-V6tgRVi62jRwTm0Hglky3Scwjr/AKFBFtS+MdbsBr7UOuiu1TKLPc6xfPiyEN1+bYqjEtjxwGsHgahcJsd1rNg==", + "devOptional": true + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.7.0.tgz", + "integrity": "sha512-zIn/qmO+N/3FYe7/L9o+yZseIU8ivh4NdPKSkQRIHfg2QVTVMnbhGoTcecbxfVubeTp+DjcbjS0H9fCuM4W04w==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.7.0", + "@prisma/engines-version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", + "@prisma/get-platform": "5.7.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.7.0.tgz", + "integrity": "sha512-ZeV/Op4bZsWXuw5Tg05WwRI8BlKiRFhsixPcAM+5BKYSiUZiMKIi713tfT3drBq8+T0E1arNZgYSA9QYcglWNA==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.7.0" + } }, "node_modules/@sapphire/async-queue": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.0.tgz", - "integrity": "sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.1.tgz", + "integrity": "sha512-1RdpsmDQR/aWfp8oJzPtn4dNQrbpqSL5PIA0uAB/XwerPXUf994Ug1au1e7uGcD7ei8/F63UDjr5GWps1g/HxQ==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, "node_modules/@sapphire/shapeshift": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.2.tgz", - "integrity": "sha512-YRbCXWy969oGIdqR/wha62eX8GNHsvyYi0Rfd4rNW6tSVVa8p0ELiMEuOH/k8rgtvRoM+EMV7Csqz77YdwiDpA==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.4.tgz", + "integrity": "sha512-SiOoCBmm8O7QuadLJnX4V0tAkhC54NIOZJtmvw+5zwnHaiulGkjY02wxCuK8Gf4V540ILmGz+UulC0U8mrOZjg==", "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" @@ -305,65 +359,68 @@ } }, "node_modules/@types/fold-to-ascii": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/fold-to-ascii/-/fold-to-ascii-5.0.0.tgz", - "integrity": "sha512-zaaLJcf8jPuVVYl6v+mSMaOMJNgkrDsYweu7Oa5RODIKgX9+Yu6Ng6/IY9zylwIurt0iQiDM0SN8agCOhLrKUA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/fold-to-ascii/-/fold-to-ascii-5.0.2.tgz", + "integrity": "sha512-5aD3uXARTpE87W75ZWQLGjiWoT65sFA28JCb3VEXB5O1w6mh2/ceVt6/mCV0vI36STPsCiXM4ZnRtQXvBOIa/A==", "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/node": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", - "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "node_modules/@types/require-directory": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/require-directory/-/require-directory-2.1.3.tgz", - "integrity": "sha512-B4uMLVwf83xg/o6RsEX8ifMDHyBgNhwU0JCpveJeT1DLoIDjgHjNH3ZDcPoyoJVAfa++wJfhiFPG3B/ztwhVww==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@types/require-directory/-/require-directory-2.1.6.tgz", + "integrity": "sha512-b+IXLaj2/pjPLBi7z/0Y5rSWAwn73w4u0Om7dHl0z2RL+ZNOeIfosrGd/bLEeUpcSSuUzOXgF1RrshzLEx9+7Q==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "node_modules/@types/ws": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.6.tgz", - "integrity": "sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==", + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", + "integrity": "sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz", - "integrity": "sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", + "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/type-utils": "6.7.3", - "@typescript-eslint/utils": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/type-utils": "6.14.0", + "@typescript-eslint/utils": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -389,15 +446,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", - "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", + "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", "debug": "^4.3.4" }, "engines": { @@ -417,13 +474,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz", - "integrity": "sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", + "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3" + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -434,13 +491,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz", - "integrity": "sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", + "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.3", - "@typescript-eslint/utils": "6.7.3", + "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/utils": "6.14.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -461,9 +518,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.3.tgz", - "integrity": "sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", + "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -474,13 +531,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz", - "integrity": "sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", + "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/visitor-keys": "6.7.3", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/visitor-keys": "6.14.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -501,17 +558,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.3.tgz", - "integrity": "sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", + "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.3", - "@typescript-eslint/types": "6.7.3", - "@typescript-eslint/typescript-estree": "6.7.3", + "@typescript-eslint/scope-manager": "6.14.0", + "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/typescript-estree": "6.14.0", "semver": "^7.5.4" }, "engines": { @@ -526,12 +583,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz", - "integrity": "sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", + "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.3", + "@typescript-eslint/types": "6.14.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -542,10 +599,16 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vladfrangu/async_event_emitter": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz", - "integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.4.tgz", + "integrity": "sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" @@ -563,9 +626,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -687,17 +750,6 @@ "node": ">=8" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -841,29 +893,29 @@ } }, "node_modules/discord-api-types": { - "version": "0.37.50", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", - "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + "version": "0.37.61", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.61.tgz", + "integrity": "sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==" }, "node_modules/discord.js": { - "version": "14.13.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.13.0.tgz", - "integrity": "sha512-Kufdvg7fpyTEwANGy9x7i4od4yu5c6gVddGi5CKm4Y5a6sF0VBODObI3o0Bh7TGCj0LfNT8Qp8z04wnLFzgnbA==", + "version": "14.14.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.14.1.tgz", + "integrity": "sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==", "dependencies": { - "@discordjs/builders": "^1.6.5", - "@discordjs/collection": "^1.5.3", - "@discordjs/formatters": "^0.3.2", - "@discordjs/rest": "^2.0.1", - "@discordjs/util": "^1.0.1", - "@discordjs/ws": "^1.0.1", - "@sapphire/snowflake": "^3.5.1", - "@types/ws": "^8.5.5", - "discord-api-types": "0.37.50", - "fast-deep-equal": "^3.1.3", - "lodash.snakecase": "^4.1.1", - "tslib": "^2.6.1", - "undici": "5.22.1", - "ws": "^8.13.0" + "@discordjs/builders": "^1.7.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.3.3", + "@discordjs/rest": "^2.1.0", + "@discordjs/util": "^1.0.2", + "@discordjs/ws": "^1.0.2", + "@sapphire/snowflake": "3.5.1", + "@types/ws": "8.5.9", + "discord-api-types": "0.37.61", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "2.6.2", + "undici": "5.27.2", + "ws": "8.14.2" }, "engines": { "node": ">=16.11.0" @@ -894,18 +946,19 @@ } }, "node_modules/eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -1048,9 +1101,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1137,17 +1190,17 @@ } }, "node_modules/flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.2.7", + "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { @@ -1194,6 +1247,14 @@ "node": ">= 12.20" } }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1233,9 +1294,9 @@ } }, "node_modules/globals": { - "version": "13.22.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", - "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1296,9 +1357,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" @@ -1426,9 +1487,9 @@ "dev": true }, "node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { "json-buffer": "3.0.1" @@ -1491,9 +1552,9 @@ } }, "node_modules/magic-bytes.js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.2.0.tgz", - "integrity": "sha512-NFrX8tqiYYrIiMQ3f0UkqG8INKzF8Lz7Jo2c5Ut6b5/Bzp/sr2z6dQoXPSLVDaioM2N6/k+3sDnD/y4Xpx6lSQ==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.7.0.tgz", + "integrity": "sha512-YzVU2+/hrjwx8xcgAw+ffNq3jkactpj+f1iSL4LonrFKhvnwDzHSqtFdk/MMRP53y9ScouJ7cKEnqYsJwsHoYA==" }, "node_modules/md5": { "version": "2.3.0", @@ -1616,9 +1677,9 @@ } }, "node_modules/openai": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.10.0.tgz", - "integrity": "sha512-II4b5/7qzwYkqA9MSjgqdofCc798EW+dtF2h6qNaVLet+qO7FShAJTWnoyzb50J4ZH1rPxRFAsmDLIhY3PT6DQ==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.21.0.tgz", + "integrity": "sha512-HT0Jm2iGI5+Maq7Da/DPTeIAxNvpa5pamkhlNnJJAqJgVjaFDvMUBjGhFJoVohkYWwZjM9oSyfSC0eoVNPioaQ==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", @@ -1627,16 +1688,20 @@ "digest-fetch": "^1.3.0", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.7", + "web-streams-polyfill": "^3.2.1" }, "bin": { "openai": "bin/cli" } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.18.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.0.tgz", - "integrity": "sha512-3xA4X31gHT1F1l38ATDIL9GpRLdwVhnEFC8Uikv5ZLlXATwrCYyPq7ZWHxzxc3J/30SUiwiYT+bQe0/XvKlWbw==" + "version": "18.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", + "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/optionator": { "version": "0.9.3", @@ -1755,13 +1820,13 @@ } }, "node_modules/prisma": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz", - "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.7.0.tgz", + "integrity": "sha512-0rcfXO2ErmGAtxnuTNHQT9ztL0zZheQjOI/VNJzdq87C3TlGPQtMqtM+KCwU6XtmkoEr7vbCQqA7HF9IY0ST+Q==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.3.1" + "@prisma/engines": "5.7.0" }, "bin": { "prisma": "build/index.js" @@ -1771,9 +1836,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -1909,14 +1974,6 @@ "node": ">=8" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -2023,9 +2080,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2035,16 +2092,21 @@ } }, "node_modules/undici": { - "version": "5.22.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.22.1.tgz", - "integrity": "sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==", + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.27.2.tgz", + "integrity": "sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==", "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2055,11 +2117,11 @@ } }, "node_modules/web-streams-polyfill": { - "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", "engines": { - "node": ">= 14" + "node": ">= 8" } }, "node_modules/webidl-conversions": { diff --git a/package.json b/package.json index a3dee49..4af91ed 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "author": "Wroclaw", "license": "MIT", "dependencies": { - "@prisma/client": "^5.0.0", + "@prisma/client": "5.7.0", "discord.js": "^14.8.0", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", @@ -25,6 +25,6 @@ "@typescript-eslint/eslint-plugin": "^6.2.0", "@typescript-eslint/parser": "^6.2.0", "eslint": "^8.46.0", - "prisma": "^5.0.0" + "prisma": "5.7.0" } } From 722862ded3ee6b0a91819abe138a00218f2cdd24 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Sun, 12 Nov 2023 22:35:43 +0100 Subject: [PATCH 18/39] Add shell.nix to development util on nixos system --- shell.nix | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 shell.nix diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..b520ade --- /dev/null +++ b/shell.nix @@ -0,0 +1,87 @@ +{ pkgs ? import {} }: + +let + # Updating this package will force an update for nodePackages.prisma. The + # version of prisma-engines and nodePackages.prisma must be the same for them to + # function correctly. + prisma-version = "5.7.0"; + prisma-src = pkgs.fetchFromGitHub { + owner = "prisma"; + repo = "prisma-engines"; + rev = prisma-version; + hash = "sha256-gZEz0UtgNwumsZbweAyx3TOVHJshpBigc9pzWN7Gb/A="; + }; + new-prisma-engines = pkgs.rustPlatform.buildRustPackage { + pname = "prisma-engines"; + version = prisma-version; + + src = builtins.storePath prisma-src; + + # Use system openssl. + OPENSSL_NO_VENDOR = 1; + + nativeBuildInputs = [ pkgs.pkg-config pkgs.git ]; + + buildInputs = [ + pkgs.openssl + pkgs.protobuf + ]; + + cargoLock = { + lockFile = "${prisma-src}/Cargo.lock"; + outputHashes = { + "cuid-1.3.2" = "sha256-ZihFrLerEIOdbJggaBbByRbC1sZRvF4M0LN2albB7vA="; + "barrel-0.6.6-alpha.0" = "sha256-USh0lQ1z+3Spgc69bRFySUzhuY79qprLlEExTmYWFN8="; + "graphql-parser-0.3.0" = "sha256-0ZAsj2mW6fCLhwTETucjbu4rPNzfbNiHu2wVTBlTNe4="; + "mysql_async-0.31.3" = "sha256-QIO9s0Upc0/1W7ux1RNJNGKqzO4gB4gMV3NoakAbxkQ="; + "postgres-native-tls-0.5.0" = "sha256-UYPsxhCkXXWk8yPbqjNS0illwjS5mVm3Z/jFwpVwqfw="; + }; + }; + + preBuild = '' + export OPENSSL_DIR=${pkgs.lib.getDev pkgs.openssl} + export OPENSSL_LIB_DIR=${pkgs.lib.getLib pkgs.openssl}/lib + + export PROTOC=${pkgs.protobuf}/bin/protoc + export PROTOC_INCLUDE="${pkgs.protobuf}/include"; + + export SQLITE_MAX_VARIABLE_NUMBER=250000 + export SQLITE_MAX_EXPR_DEPTH=10000 + ''; + + cargoBuildFlags = [ + "-p" "query-engine" + "-p" "query-engine-node-api" + "-p" "schema-engine-cli" + "-p" "prisma-fmt" + ]; + + postInstall = '' + mv $out/lib/libquery_engine${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/libquery_engine.node + ''; + + # Tests are long to compile + doCheck = false; + + # meta = with lib; { + # description = "A collection of engines that power the core stack for Prisma"; + # homepage = "https://www.prisma.io/"; + # license = licenses.asl20; + # platforms = platforms.unix; + # maintainers = with maintainers; [ pimeys tomhoule ivan aqrln ]; + # }; + }; +in +pkgs.mkShell { + nativeBuildInputs = [ + new-prisma-engines + pkgs.nodejs_18 + pkgs.openssl + ]; + shellHook = '' + export PRISMA_SCHEMA_ENGINE_BINARY="${new-prisma-engines}/bin/schema-engine" + export PRISMA_QUERY_ENGINE_BINARY="${new-prisma-engines}/bin/query-engine" + export PRISMA_QUERY_ENGINE_LIBRARY="${new-prisma-engines}/lib/libquery_engine.node" + export PRISMA_FMT_BINARY="${new-prisma-engines}/bin/prisma-fmt" + ''; +} From 02a5b0f7b97cc71e61f7fd811ec652a4995315cf Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 13 Dec 2023 17:42:59 +0100 Subject: [PATCH 19/39] Remove getTime model function it lead to higher usage of tokens. --- src/configDefault.ts | 10 ---------- src/funcitonManager.ts | 19 +------------------ 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/configDefault.ts b/src/configDefault.ts index 65785a9..12ce515 100644 --- a/src/configDefault.ts +++ b/src/configDefault.ts @@ -8,7 +8,6 @@ import IQuota from "./IQuota"; import MessageCount from "./quota/messageCount"; export interface IConfigRequired { - readonly calendarParams: Intl.DateTimeFormatOptions; /** Tokens to authentiate with */ readonly tokens: { readonly Discord: string; @@ -52,15 +51,6 @@ function envAsNumber(key: string): number | undefined { } const defaultConfig: IConfigRequired = { - calendarParams: { - weekday: "short", - year: "numeric", - month: "short", - day: "numeric", - hour: "2-digit", - minute: "2-digit", - hour12: false, - }, tokens: { Discord: envAsString("TOKENS__DISCORD") ?? "", OpenAI: envAsString("TOKENS__OPENAI") ?? "", diff --git a/src/funcitonManager.ts b/src/funcitonManager.ts index 9bcb0ec..41e35c1 100644 --- a/src/funcitonManager.ts +++ b/src/funcitonManager.ts @@ -1,7 +1,5 @@ import { ChatCompletionCreateParams, ChatCompletionMessage, ChatCompletionMessageParam } from "openai/resources/chat"; -import { config } from "./index"; - type parameterMap = { string: string, number: number, @@ -53,7 +51,7 @@ export default class FunctionManager { store = new Map(); constructor() { - this.store.set("getTime", new GetTime()); + // TODO: import functions from functions directory } public getFunctions(): ChatCompletionFunctions[] { @@ -95,18 +93,3 @@ export default class FunctionManager { }; } } - -// buildins - -class GetTime extends OpenAIFunction> { - name = "getTime"; - description = "Gets current date and time with a timezone attached"; - parameters = { - type: "object" as const, - properties: {} as Record, - }; - - execute(): string { - return `${Intl.DateTimeFormat().resolvedOptions().timeZone}): ${new Date().toLocaleString("en-US", config.calendarParams)}`; - } -} From 24e85f535a7fd14796eae6c9f9286751c5ac1b31 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 13 Dec 2023 19:48:30 +0100 Subject: [PATCH 20/39] "Gracefully" exit when receiving sigint --- Dockerfile | 1 + src/index.ts | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9ef0693..32d0e7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,3 +17,4 @@ RUN npx tsc # Run the app CMD ["node", "dist/src/index.js"] +STOPSIGNAL SIGINT diff --git a/src/index.ts b/src/index.ts index 27e5c45..e0506ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,4 +63,17 @@ discord.on("messageCreate", message => { return queueRequest(message); }); -if (require.main === module) void discord.login(config.tokens.Discord); +if (require.main === module) { + void discord.login(config.tokens.Discord); + process.on("SIGINT", () => { + console.log("got SIGINT, exiting"); + //FIXME: finish executing requests then exit + discord.destroy() + .then(() => process.exit()) + .catch((e) => { + console.error("Failed to gracefully exit"); + console.error(e); + process.exit(); + }); + }); +} From 74359067d0e31c7a5ad80a72f01a219407e33ca7 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 13 Dec 2023 21:08:09 +0100 Subject: [PATCH 21/39] functionManager: don't return empty function array for openai openai doesn't accept empty function parameter, it was discovered after I removed the testing buildin function --- src/execution.ts | 2 +- src/funcitonManager.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/execution.ts b/src/execution.ts index 3b8e2fd..44e5710 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -246,7 +246,7 @@ async function executeFromQueue(channel: string) { ...config.chatCompletionParams, messages: OpenAImessages, // FIXME: don't use new instance of FunctionManager - functions: new FunctionManager().getFunctions(), + functions: new FunctionManager().getFunctionsForOpenAi(), }); logUsedTokens(answer, message, ++functionRanCounter); diff --git a/src/funcitonManager.ts b/src/funcitonManager.ts index 41e35c1..11b1bac 100644 --- a/src/funcitonManager.ts +++ b/src/funcitonManager.ts @@ -62,6 +62,11 @@ export default class FunctionManager { return rvalue; } + public getFunctionsForOpenAi(): ChatCompletionFunctions[] | undefined { + const rvalue = this.getFunctions(); + return rvalue.length > 0 ? rvalue : undefined; + } + public handleFunction(request: ChatCompletionFunctionCall): ChatCompletionMessageParam { // eslint-disable-next-line @typescript-eslint/no-explicit-any let parsedArguments: any; From dc01146ee82e05f5656ae7cb54d074d21ba0be6a Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Mon, 25 Dec 2023 16:09:35 +0100 Subject: [PATCH 22/39] ignore @everyone mentions --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index e0506ab..a565a3f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,7 +58,7 @@ discord.on("ready", event => { discord.on("messageCreate", message => { if (message.author.bot) return; - if (!message.mentions.has(message.client.user)) return; + if (!message.mentions.has(message.client.user, { ignoreEveryone: true })) return; return queueRequest(message); }); From 91232e99a7b251aea3b013d4461550b8e223ce6e Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 23 Apr 2024 16:47:08 +0200 Subject: [PATCH 23/39] Update dependencies --- package-lock.json | 510 +++++++++++++++++++++++++--------------------- package.json | 16 +- shell.nix | 25 +-- 3 files changed, 293 insertions(+), 258 deletions(-) diff --git a/package-lock.json b/package-lock.json index f35449d..85b46e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,21 +9,21 @@ "version": "0.1.0", "license": "MIT", "dependencies": { - "@prisma/client": "5.7.0", - "discord.js": "^14.8.0", + "@prisma/client": "5.13.0", + "discord.js": "14.14.1", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", - "openai": "^4.10.0", + "openai": "^4.38.3", "require-directory": "^2.1.1", - "typescript": "^5.1.6" + "typescript": "^5.4.5" }, "devDependencies": { "@types/fold-to-ascii": "^5.0.0", "@types/require-directory": "^2.1.2", - "@typescript-eslint/eslint-plugin": "^6.2.0", - "@typescript-eslint/parser": "^6.2.0", - "eslint": "^8.46.0", - "prisma": "5.7.0" + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", + "eslint": "^8.57.0", + "prisma": "5.13.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -180,37 +180,81 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", "engines": { "node": ">=14" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -225,9 +269,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -266,9 +310,9 @@ } }, "node_modules/@prisma/client": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.7.0.tgz", - "integrity": "sha512-cZmglCrfNbYpzUtz7HscVHl38e9CrUs31nrVoGUK1nIPXGgt8hT4jj2s657UXcNdQ/jBUxDgGmHyu2Nyrq1txg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.13.0.tgz", + "integrity": "sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg==", "hasInstallScript": true, "engines": { "node": ">=16.13" @@ -283,70 +327,69 @@ } }, "node_modules/@prisma/debug": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.7.0.tgz", - "integrity": "sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.13.0.tgz", + "integrity": "sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ==", "devOptional": true }, "node_modules/@prisma/engines": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.7.0.tgz", - "integrity": "sha512-TkOMgMm60n5YgEKPn9erIvFX2/QuWnl3GBo6yTRyZKk5O5KQertXiNnrYgSLy0SpsKmhovEPQb+D4l0SzyE7XA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.13.0.tgz", + "integrity": "sha512-hIFLm4H1boj6CBZx55P4xKby9jgDTeDG0Jj3iXtwaaHmlD5JmiDkZhh8+DYWkTGchu+rRF36AVROLnk0oaqhHw==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/debug": "5.7.0", - "@prisma/engines-version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", - "@prisma/fetch-engine": "5.7.0", - "@prisma/get-platform": "5.7.0" + "@prisma/debug": "5.13.0", + "@prisma/engines-version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "@prisma/fetch-engine": "5.13.0", + "@prisma/get-platform": "5.13.0" } }, "node_modules/@prisma/engines-version": { - "version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9.tgz", - "integrity": "sha512-V6tgRVi62jRwTm0Hglky3Scwjr/AKFBFtS+MdbsBr7UOuiu1TKLPc6xfPiyEN1+bYqjEtjxwGsHgahcJsd1rNg==", + "version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b.tgz", + "integrity": "sha512-AyUuhahTINGn8auyqYdmxsN+qn0mw3eg+uhkp8zwknXYIqoT3bChG4RqNY/nfDkPvzWAPBa9mrDyBeOnWSgO6A==", "devOptional": true }, "node_modules/@prisma/fetch-engine": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.7.0.tgz", - "integrity": "sha512-zIn/qmO+N/3FYe7/L9o+yZseIU8ivh4NdPKSkQRIHfg2QVTVMnbhGoTcecbxfVubeTp+DjcbjS0H9fCuM4W04w==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.13.0.tgz", + "integrity": "sha512-Yh4W+t6YKyqgcSEB3odBXt7QyVSm0OQlBSldQF2SNXtmOgMX8D7PF/fvH6E6qBCpjB/yeJLy/FfwfFijoHI6sA==", "devOptional": true, "dependencies": { - "@prisma/debug": "5.7.0", - "@prisma/engines-version": "5.7.0-41.79fb5193cf0a8fdbef536e4b4a159cad677ab1b9", - "@prisma/get-platform": "5.7.0" + "@prisma/debug": "5.13.0", + "@prisma/engines-version": "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b", + "@prisma/get-platform": "5.13.0" } }, "node_modules/@prisma/get-platform": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.7.0.tgz", - "integrity": "sha512-ZeV/Op4bZsWXuw5Tg05WwRI8BlKiRFhsixPcAM+5BKYSiUZiMKIi713tfT3drBq8+T0E1arNZgYSA9QYcglWNA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.13.0.tgz", + "integrity": "sha512-B/WrQwYTzwr7qCLifQzYOmQhZcFmIFhR81xC45gweInSUn2hTEbfKUPd2keAog+y5WI5xLAFNJ3wkXplvSVkSw==", "devOptional": true, "dependencies": { - "@prisma/debug": "5.7.0" + "@prisma/debug": "5.13.0" } }, "node_modules/@sapphire/async-queue": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.1.tgz", - "integrity": "sha512-1RdpsmDQR/aWfp8oJzPtn4dNQrbpqSL5PIA0uAB/XwerPXUf994Ug1au1e7uGcD7ei8/F63UDjr5GWps1g/HxQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz", + "integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==", "engines": { "node": ">=v14.0.0", "npm": ">=7.0.0" } }, "node_modules/@sapphire/shapeshift": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.4.tgz", - "integrity": "sha512-SiOoCBmm8O7QuadLJnX4V0tAkhC54NIOZJtmvw+5zwnHaiulGkjY02wxCuK8Gf4V540ILmGz+UulC0U8mrOZjg==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz", + "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==", "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" }, "engines": { - "node": ">=v14.0.0", - "npm": ">=7.0.0" + "node": ">=v16" } }, "node_modules/@sapphire/snowflake": { @@ -371,17 +414,17 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", "dependencies": { "@types/node": "*", "form-data": "^4.0.0" @@ -397,9 +440,9 @@ } }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/ws": { @@ -411,33 +454,33 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", - "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/type-utils": "6.14.0", - "@typescript-eslint/utils": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -446,26 +489,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", - "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -474,16 +517,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", - "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -491,25 +534,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", - "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/utils": "6.14.0", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -518,12 +561,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", - "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -531,21 +574,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", - "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -558,41 +602,41 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", - "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "semver": "^7.6.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", - "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -626,9 +670,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -723,19 +767,13 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" - }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -775,14 +813,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "engines": { - "node": "*" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -832,14 +862,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "engines": { - "node": "*" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -871,15 +893,6 @@ "node": ">=0.4.0" } }, - "node_modules/digest-fetch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", - "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", - "dependencies": { - "base-64": "^0.1.0", - "md5": "^2.3.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -946,16 +959,16 @@ } }, "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -1028,6 +1041,28 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -1141,9 +1176,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -1204,9 +1239,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/fold-to-ascii": { @@ -1293,6 +1328,28 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -1357,9 +1414,9 @@ } }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -1406,11 +1463,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1552,19 +1604,9 @@ } }, "node_modules/magic-bytes.js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.7.0.tgz", - "integrity": "sha512-YzVU2+/hrjwx8xcgAw+ffNq3jkactpj+f1iSL4LonrFKhvnwDzHSqtFdk/MMRP53y9ScouJ7cKEnqYsJwsHoYA==" - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==" }, "node_modules/merge2": { "version": "1.4.1", @@ -1608,15 +1650,18 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { @@ -1677,15 +1722,14 @@ } }, "node_modules/openai": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.21.0.tgz", - "integrity": "sha512-HT0Jm2iGI5+Maq7Da/DPTeIAxNvpa5pamkhlNnJJAqJgVjaFDvMUBjGhFJoVohkYWwZjM9oSyfSC0eoVNPioaQ==", + "version": "4.38.3", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.38.3.tgz", + "integrity": "sha512-mIL9WtrFNOanpx98mJ+X/wkoepcxdqqu0noWFoNQHl/yODQ47YM7NEYda7qp8JfjqpLFVxY9mQhshoS/Fqac0A==", "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", - "digest-fetch": "^1.3.0", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7", @@ -1696,9 +1740,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", - "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", + "version": "18.19.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.31.tgz", + "integrity": "sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA==", "dependencies": { "undici-types": "~5.26.4" } @@ -1820,13 +1864,13 @@ } }, "node_modules/prisma": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.7.0.tgz", - "integrity": "sha512-0rcfXO2ErmGAtxnuTNHQT9ztL0zZheQjOI/VNJzdq87C3TlGPQtMqtM+KCwU6XtmkoEr7vbCQqA7HF9IY0ST+Q==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.13.0.tgz", + "integrity": "sha512-kGtcJaElNRAdAGsCNykFSZ7dBKpL14Cbs+VaQ8cECxQlRPDjBlMHNFYeYt0SKovAVy2Y65JXQwB3A5+zIQwnTg==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.7.0" + "@prisma/engines": "5.13.0" }, "bin": { "prisma": "build/index.js" @@ -1930,9 +1974,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2034,21 +2078,21 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" } }, "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" }, "node_modules/tslib": { "version": "2.6.2", @@ -2080,9 +2124,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2117,9 +2161,9 @@ } }, "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "engines": { "node": ">= 8" } diff --git a/package.json b/package.json index 4af91ed..af0fdf1 100644 --- a/package.json +++ b/package.json @@ -11,20 +11,20 @@ "author": "Wroclaw", "license": "MIT", "dependencies": { - "@prisma/client": "5.7.0", - "discord.js": "^14.8.0", + "@prisma/client": "5.13.0", + "discord.js": "14.14.1", "fold-to-ascii": "^5.0.1", "gpt-3-encoder": "^1.1.4", - "openai": "^4.10.0", + "openai": "^4.38.3", "require-directory": "^2.1.1", - "typescript": "^5.1.6" + "typescript": "^5.4.5" }, "devDependencies": { "@types/fold-to-ascii": "^5.0.0", "@types/require-directory": "^2.1.2", - "@typescript-eslint/eslint-plugin": "^6.2.0", - "@typescript-eslint/parser": "^6.2.0", - "eslint": "^8.46.0", - "prisma": "5.7.0" + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", + "eslint": "^8.57.0", + "prisma": "5.13.0" } } diff --git a/shell.nix b/shell.nix index b520ade..1759471 100644 --- a/shell.nix +++ b/shell.nix @@ -1,17 +1,16 @@ -{ pkgs ? import {} }: +{ pkgs ? import {} +, unstable ? import {} +}: let - # Updating this package will force an update for nodePackages.prisma. The - # version of prisma-engines and nodePackages.prisma must be the same for them to - # function correctly. - prisma-version = "5.7.0"; + prisma-version = "5.13.0"; prisma-src = pkgs.fetchFromGitHub { owner = "prisma"; repo = "prisma-engines"; rev = prisma-version; - hash = "sha256-gZEz0UtgNwumsZbweAyx3TOVHJshpBigc9pzWN7Gb/A="; + hash = "sha256-8LC2RV3FRr1F0TZxQNxvvEoTyhKusgzB5omlxLAnHG0="; }; - new-prisma-engines = pkgs.rustPlatform.buildRustPackage { + new-prisma-engines = unstable.rustPlatform.buildRustPackage { pname = "prisma-engines"; version = prisma-version; @@ -30,10 +29,10 @@ let cargoLock = { lockFile = "${prisma-src}/Cargo.lock"; outputHashes = { - "cuid-1.3.2" = "sha256-ZihFrLerEIOdbJggaBbByRbC1sZRvF4M0LN2albB7vA="; + "cuid-1.3.2" = "sha256-qBu1k/dJiA6rWBwk4nOOqouIneD9h2TTBT8tvs0TDfA="; "barrel-0.6.6-alpha.0" = "sha256-USh0lQ1z+3Spgc69bRFySUzhuY79qprLlEExTmYWFN8="; "graphql-parser-0.3.0" = "sha256-0ZAsj2mW6fCLhwTETucjbu4rPNzfbNiHu2wVTBlTNe4="; - "mysql_async-0.31.3" = "sha256-QIO9s0Upc0/1W7ux1RNJNGKqzO4gB4gMV3NoakAbxkQ="; + "mysql_async-0.31.3" = "sha256-2wOupQ/LFV9pUifqBLwTvA0tySv+XWbxHiqs7iTzvvg="; "postgres-native-tls-0.5.0" = "sha256-UYPsxhCkXXWk8yPbqjNS0illwjS5mVm3Z/jFwpVwqfw="; }; }; @@ -62,14 +61,6 @@ let # Tests are long to compile doCheck = false; - - # meta = with lib; { - # description = "A collection of engines that power the core stack for Prisma"; - # homepage = "https://www.prisma.io/"; - # license = licenses.asl20; - # platforms = platforms.unix; - # maintainers = with maintainers; [ pimeys tomhoule ivan aqrln ]; - # }; }; in pkgs.mkShell { From 0e5c8d22ccb3623060f541b55f26ef800f04d8e7 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 23 Apr 2024 17:46:24 +0200 Subject: [PATCH 24/39] functionManager: retrofit for tool calls api --- src/execution.ts | 10 +++--- src/funcitonManager.ts | 75 ++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/execution.ts b/src/execution.ts index 44e5710..d68f7c0 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -246,7 +246,7 @@ async function executeFromQueue(channel: string) { ...config.chatCompletionParams, messages: OpenAImessages, // FIXME: don't use new instance of FunctionManager - functions: new FunctionManager().getFunctionsForOpenAi(), + tools: new FunctionManager().getToolsForOpenAi(), }); logUsedTokens(answer, message, ++functionRanCounter); @@ -254,13 +254,11 @@ async function executeFromQueue(channel: string) { generatedMessage = answer.choices[0].message; if (!generatedMessage) throw new Error("Empty message received"); - // handle function calls - if (generatedMessage.function_call) { + // handle tool calls + if (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0) { OpenAImessages.push(generatedMessage); // FIXME: don't use new instance of FunctionManager - OpenAImessages.push( - new FunctionManager().handleFunction(generatedMessage.function_call) - ); + OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); } } while (generatedMessage.function_call); diff --git a/src/funcitonManager.ts b/src/funcitonManager.ts index 11b1bac..6ab27d0 100644 --- a/src/funcitonManager.ts +++ b/src/funcitonManager.ts @@ -1,4 +1,9 @@ -import { ChatCompletionCreateParams, ChatCompletionMessage, ChatCompletionMessageParam } from "openai/resources/chat"; +import { FunctionDefinition } from "openai/resources"; +import { + ChatCompletionMessageParam +, ChatCompletionMessageToolCall +, ChatCompletionTool +} from "openai/resources/chat"; type parameterMap = { string: string, @@ -11,8 +16,10 @@ type OpenAIFunctionRequestData = { [name in keyof T]: T[name]; }; -type ChatCompletionFunctions = ChatCompletionCreateParams.Function; -type ChatCompletionFunctionCall = ChatCompletionMessage.FunctionCall; +type ChatCompletionToolDefinition = ChatCompletionTool; +type ChatCompletionToolCall = ChatCompletionMessageToolCall; + +type ChatCompletionFunctionDefinition = FunctionDefinition; /** * Represents the function that can be ran by the OpenAI model @@ -33,7 +40,7 @@ export interface OpenAIFunction { } export abstract class OpenAIFunction { - getSettings(): ChatCompletionFunctions { + getSettings(): ChatCompletionFunctionDefinition { return { name: this.name, description: this.description, @@ -41,7 +48,7 @@ export abstract class OpenAIFunction { }; } - abstract execute(data: OpenAIFunctionRequestData): string; + abstract execute(data: OpenAIFunctionRequestData): Promise; } /* @@ -54,47 +61,67 @@ export default class FunctionManager { // TODO: import functions from functions directory } - public getFunctions(): ChatCompletionFunctions[] { - const rvalue: ChatCompletionFunctions[] = []; + public getTools(): ChatCompletionToolDefinition[] { + const rvalue: ChatCompletionToolDefinition[] = []; for (const [, value] of this.store) { - rvalue.push(value.getSettings()); + rvalue.push({type: "function", function: value.getSettings()}); } return rvalue; } - public getFunctionsForOpenAi(): ChatCompletionFunctions[] | undefined { - const rvalue = this.getFunctions(); + public getToolsForOpenAi(): ChatCompletionTool[] | undefined { + const rvalue = this.getTools(); return rvalue.length > 0 ? rvalue : undefined; } - public handleFunction(request: ChatCompletionFunctionCall): ChatCompletionMessageParam { + public handleFunction(request: ChatCompletionToolCall): Promise { // eslint-disable-next-line @typescript-eslint/no-explicit-any let parsedArguments: any; - const functionToRun = this.store.get(request.name ?? ""); + const functionToRun = this.store.get(request.function.name); // check if the function is registered if (!functionToRun) { - return { + return Promise.resolve({ role: "system", - content: "Only use functions that were provided to you", - }; + content: `Only use functions that were provided to you (response for tool call ID: ${request.id})`, + }); } try { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - parsedArguments = JSON.parse(request.arguments ?? ""); + parsedArguments = JSON.parse(request.function.arguments); } catch (e) { - console.error("Function arguments raw: " + request.arguments); - throw new Error(`Failed to parse the function JSON arguments when running function [${request.name}]`, {cause: e}); + console.error("Function arguments raw: " + request.function.arguments); + throw new Error(`Failed to parse the function JSON arguments when running function [${request.function.name}]`, {cause: e}); } // FIXME: Verify if the parsedArguments matches the requested function argument declaration. - return { - role: "function", - name: request.name, - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - content: functionToRun.execute(parsedArguments), - }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + return functionToRun.execute(parsedArguments).then(content => { + return { + role: "tool", + tool_call_id: request.id, + content: content, + }; + }); + } + + public handleToolCall(call: ChatCompletionToolCall): Promise { + if (call.type === "function") { + return this.handleFunction(call); + } + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + throw new Error(`Unsupported tool call type: ${call.type || "never"}`); + } + + public handleToolCalls(calls: ChatCompletionToolCall[]) { + const rvalue: Promise[] = []; + for (const call of calls) { + if (call.type === "function") { + rvalue.push(this.handleToolCall(call)); + } + } + return Promise.all(rvalue); } } From 63cb52e7f47e9c6da3e1342369d7c5101f7ed633 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 23 Apr 2024 20:56:55 +0200 Subject: [PATCH 25/39] Command: Add integration and context types While discord api supports that, discord api types, which discord.js depends on does not. --- scripts/pushCommands.ts | 18 ++++++++++++++++- src/command.ts | 44 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/scripts/pushCommands.ts b/scripts/pushCommands.ts index 25ee04e..3c5f093 100644 --- a/scripts/pushCommands.ts +++ b/scripts/pushCommands.ts @@ -4,13 +4,25 @@ import { REST, RESTGetAPIOAuth2CurrentApplicationResult, RESTPostAPIApplicationC import { config } from "../src/index"; import requireDirectory from "require-directory"; -import Command from "../src/command"; +import + Command +, { + ApplicationIntegrationType +, InteractionContextTypes +, InteractionTypeMap +} from "../src/command"; const post: RESTPostAPIApplicationCommandsJSONBody[] = []; const guildId = process.argv.slice(2)[0]; const importedCommands = requireDirectory(module, "../src/commands"); +function isGuildCommand(command: Command): boolean { + // guild Commmand is when it's a guild install and context is guild (and these are defaults if not provided) + return (command.integration_types?.includes(ApplicationIntegrationType.Guild_Install) ?? true) + && (command.contexts?.includes(InteractionContextTypes.Guild) ?? true); +} + for (const obj in importedCommands) { try { const allExports = importedCommands[obj] as {default: unknown}; @@ -19,6 +31,10 @@ for (const obj in importedCommands) { // @ts-expect-error const constructedExport = new defaultExport() as unknown; if (!(constructedExport instanceof Command)) throw new Error(`${obj}'s default does not extends Command`); + if (guildId && guildId !== "" && isGuildCommand(constructedExport as Command)) { + console.log(`Skipping ${obj} because it's not a guild command`); + continue; + } post.push(constructedExport.toRESTPostApplicationCommands()); } catch (e) { console.error(e); diff --git a/src/command.ts b/src/command.ts index d053e72..35be22a 100644 --- a/src/command.ts +++ b/src/command.ts @@ -2,12 +2,47 @@ import { AutocompleteInteraction, PermissionsBitField } from "discord.js"; import { RESTPostAPIApplicationCommandsJSONBody } from "discord.js"; import { APIApplicationCommandOption, ApplicationCommandType, ChatInputCommandInteraction, LocalizationMap, MessageInteraction, PermissionResolvable, UserSelectMenuInteraction } from "discord.js"; -type InteractionTypeMap = { +export type InteractionTypeMap = { + // [CommandType]: [Interaction, Description] [ApplicationCommandType.ChatInput]: [ChatInputCommandInteraction, string]; [ApplicationCommandType.Message]: [MessageInteraction, never]; [ApplicationCommandType.User]: [UserSelectMenuInteraction, never]; }; +// TODO: At time of coding, Discord api types doesn't support user installations of bot/application yet +// replace this with the types from the discord api types when it's available +/** + * https://discord.com/developers/docs/resources/application#application-object-application-integration-types + */ +export enum ApplicationIntegrationType { + Guild_Install = 0, + User_Install = 1, +} + +/** + * https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-context-types + */ +export enum InteractionContextTypes { + Guild = 0, + BotDM = 1, + PrivateChannel = 2, +} + +/** + * https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structure + */ +export type FutureRESTPostAPIApplicationCommandsJSONBody = + RESTPostAPIApplicationCommandsJSONBody +& { + /** + * @deprecated use contexts instead + */ + dm_permission?: boolean; + integration_types?: ApplicationIntegrationType[]; + contexts?: InteractionContextTypes[]; +}; + + interface Command { readonly name: string; readonly name_localizations?: LocalizationMap; @@ -17,7 +52,10 @@ interface Command { @@ -25,7 +63,7 @@ abstract class Command; - toRESTPostApplicationCommands(): RESTPostAPIApplicationCommandsJSONBody { + toRESTPostApplicationCommands(): FutureRESTPostAPIApplicationCommandsJSONBody { return { name: this.name, name_localizations: this.name_localizations, @@ -36,6 +74,8 @@ abstract class Command Date: Tue, 23 Apr 2024 21:10:52 +0200 Subject: [PATCH 26/39] Allow chatting with bot through direct messages Added new command to make the bot see direct messages, because by default these are not visible, unless bot opens direct message with the user. --- src/commands/listen.ts | 26 ++++++++++++++++++++++++++ src/index.ts | 5 ++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/commands/listen.ts diff --git a/src/commands/listen.ts b/src/commands/listen.ts new file mode 100644 index 0000000..3f1c39d --- /dev/null +++ b/src/commands/listen.ts @@ -0,0 +1,26 @@ +import {ApplicationCommandType, ChatInputCommandInteraction } from "discord.js"; + +import Command, { ApplicationIntegrationType, InteractionContextTypes } from "../command"; + +export default class Listen extends Command implements Command { + // This command exists because Discord bots don't receive direct messages + // unless they explicitly open a DM channel with the user + name = "listen"; + description = "Makes the bot listen on your direct messages"; + type = ApplicationCommandType.ChatInput; + + options = []; + integration_types = [ + ApplicationIntegrationType.Guild_Install, + ApplicationIntegrationType.User_Install + ]; + contexts = [InteractionContextTypes.BotDM]; + + async execute(interaction: ChatInputCommandInteraction) { + await interaction.user.createDM(); + await interaction.reply({ + content: "I'm now listening to your direct messages", + ephemeral: true, + }); + } +} diff --git a/src/index.ts b/src/index.ts index a565a3f..eb7a9f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ const discord = new DiscordApi.Client({ intents: [ DiscordApi.GatewayIntentBits.Guilds, DiscordApi.GatewayIntentBits.GuildMessages, + DiscordApi.GatewayIntentBits.DirectMessages, DiscordApi.GatewayIntentBits.MessageContent, ] }); @@ -58,7 +59,9 @@ discord.on("ready", event => { discord.on("messageCreate", message => { if (message.author.bot) return; - if (!message.mentions.has(message.client.user, { ignoreEveryone: true })) return; + if (!message.channel.isDMBased()) { + if (!message.mentions.has(message.client.user, { ignoreEveryone: true })) return; + } return queueRequest(message); }); From d9bee2dcf2e1e4e42c0fbb0f518efebe55799d39 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Tue, 23 Apr 2024 21:11:40 +0200 Subject: [PATCH 27/39] check-quota: define integration types and context to any --- src/commands/check-quota.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/commands/check-quota.ts b/src/commands/check-quota.ts index 3a2f5ef..4cc61d4 100644 --- a/src/commands/check-quota.ts +++ b/src/commands/check-quota.ts @@ -1,6 +1,10 @@ import { ApplicationCommandType, ChatInputCommandInteraction, APIApplicationCommandOption, ApplicationCommandOptionType, APIEmbedField } from "discord.js"; -import Command from "../command"; +import + Command +,{ApplicationIntegrationType +, InteractionContextTypes +} from "../command"; import { config } from "../index"; export default class MyLimit extends Command implements Command { @@ -21,6 +25,15 @@ export default class MyLimit extends Command implements Command { required: false, } ]; + integration_types = [ + ApplicationIntegrationType.Guild_Install, + ApplicationIntegrationType.User_Install + ]; + contexts = [ + InteractionContextTypes.Guild, + InteractionContextTypes.BotDM, + InteractionContextTypes.PrivateChannel + ]; async execute(interaction: ChatInputCommandInteraction) { let recoveryFor = interaction.options.getInteger("recovery-for", false); From b567e13f2a8b4bdbbb7bebe57a95196e5f93f186 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 24 Apr 2024 02:27:31 +0200 Subject: [PATCH 28/39] functionManager: use json-schema-to-ts to derive arguments for OpenAIFunctions --- package-lock.json | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/funcitonManager.ts | 37 +++++++++++++------------------------ 3 files changed, 52 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85b46e3..ec40cc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", "eslint": "^8.57.0", + "json-schema-to-ts": "^3.0.1", "prisma": "5.13.0" } }, @@ -35,6 +36,18 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@discordjs/builders": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.7.0.tgz", @@ -1526,6 +1539,19 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-schema-to-ts": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.0.1.tgz", + "integrity": "sha512-ANphQxnKbzLWPeYDmdoci8C9g9ttpfMx8etTlJJ8UCEmNXH9jxGkn3AAbMe+lR4N5OG/01nYxPrDyugLdsRt+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^1.2.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1908,6 +1934,12 @@ } ] }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2077,6 +2109,12 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/ts-algebra": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-1.2.2.tgz", + "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", + "dev": true + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", diff --git a/package.json b/package.json index af0fdf1..870f9c7 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", "eslint": "^8.57.0", + "json-schema-to-ts": "^3.0.1", "prisma": "5.13.0" } } diff --git a/src/funcitonManager.ts b/src/funcitonManager.ts index 6ab27d0..4860c0c 100644 --- a/src/funcitonManager.ts +++ b/src/funcitonManager.ts @@ -4,17 +4,11 @@ import { , ChatCompletionMessageToolCall , ChatCompletionTool } from "openai/resources/chat"; +import { type FromSchema, type JSONSchema } from "json-schema-to-ts"; -type parameterMap = { - string: string, - number: number, -}; - -type nameTypeMap = {[name: string]: keyof parameterMap} | Record; - -type OpenAIFunctionRequestData = { - [name in keyof T]: T[name]; -}; +type OpenAIFunctionRequestData = (JSONSchema & { + type: "object" +}); type ChatCompletionToolDefinition = ChatCompletionTool; type ChatCompletionToolCall = ChatCompletionMessageToolCall; @@ -24,31 +18,26 @@ type ChatCompletionFunctionDefinition = FunctionDefinition; /** * Represents the function that can be ran by the OpenAI model */ -export interface OpenAIFunction { +export interface OpenAIFunction< + T extends Readonly = Readonly +> { name: string, description?: string, - parameters: { - type: "object", - properties: T extends Record ? Record : { - [name in T[string]]: { - type: T[name], - description?: string, - } - }, - required?: Array, - }, + parameters: T, } -export abstract class OpenAIFunction { +export abstract class OpenAIFunction< + T extends Readonly = Readonly +> { getSettings(): ChatCompletionFunctionDefinition { return { name: this.name, description: this.description, - parameters: this.parameters, + parameters: this.parameters as Record, }; } - abstract execute(data: OpenAIFunctionRequestData): Promise; + abstract execute(data: FromSchema): Promise; } /* From 370b7623b5a6f189de96f4f877ca59216c784b4a Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Wed, 24 Apr 2024 02:38:52 +0200 Subject: [PATCH 29/39] Dockerfile: chmod dist to 777 for config.ts compilation --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index 32d0e7f..52b9fb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,11 @@ COPY src ./src COPY scripts ./scripts RUN npx tsc +# Permissions for dist directory, +# so config.ts can be compiled there during runtime +# regardless of the user of the container +RUN chmod 777 dist + # Run the app CMD ["node", "dist/src/index.js"] STOPSIGNAL SIGINT From 67a6e4d4864dd699dcfe14fb7634662d6b03fd2f Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Thu, 25 Apr 2024 01:10:30 +0200 Subject: [PATCH 30/39] execution+configDefault: retrofit for tooll_calls api --- src/configDefault.ts | 2 +- src/execution.ts | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/configDefault.ts b/src/configDefault.ts index 12ce515..620a363 100644 --- a/src/configDefault.ts +++ b/src/configDefault.ts @@ -16,7 +16,7 @@ export interface IConfigRequired { /** Messages to append at the start of every chat history when sending to API */ systemPrompt(context: Message): OpenAIMessage[]; /** OpenAI model config */ - readonly chatCompletionParams: Omit; + readonly chatCompletionParams: Omit; /** Limits for message selection */ readonly readLimits: { /** Maximum message age to include (in miliseconds) */ diff --git a/src/execution.ts b/src/execution.ts index d68f7c0..1cfcaa8 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -180,10 +180,13 @@ function logUsedTokens( functionRan: number, ) { const usage = answer.usage; - const functionName = answer.choices[0].message?.function_call?.name; + const functionNames = + answer.choices[0].message.tool_calls?.map( + v => v.type === "function" ? v.function.name : `[unknown type]` + ); if (usage !== undefined) { 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}${functionName ? " [Function: " + functionName + "]" : ""}`); + console.log(`Used ${usage.total_tokens} (${usage.prompt_tokens} + ${usage.completion_tokens}) tokens for ${getAuthor(message).tag} (${getAuthor(message).id}) in #${channelName}${functionNames && functionNames.length > 0 ? " [Tools: " + functionNames.join(", ") + "]" : ""}`); database.usage.create({ data: { @@ -193,8 +196,8 @@ function logUsedTokens( guild: message.guildId ? BigInt(message.guildId) : null, usageRequest: usage.prompt_tokens, usageResponse: usage.completion_tokens, - functionName: functionName ?? null, - functionRan: functionName ? functionRan : 0, + functionName: functionNames?.join(", ") ?? null, + functionRan: functionNames ? functionRan : 0, } }).catch((e => { console.error("Failed to push to a database"); @@ -249,6 +252,7 @@ async function executeFromQueue(channel: string) { tools: new FunctionManager().getToolsForOpenAi(), }); + functionRanCounter += answer.choices[0].message?.tool_calls?.length ?? 0; logUsedTokens(answer, message, ++functionRanCounter); generatedMessage = answer.choices[0].message; @@ -260,7 +264,7 @@ async function executeFromQueue(channel: string) { // FIXME: don't use new instance of FunctionManager OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); } - } while (generatedMessage.function_call); + } while (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0); channelQueue.stopTyping(); From d3567c36070b0c3443d24ecb2182b6f97e8d1b81 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 04:02:09 +0200 Subject: [PATCH 31/39] execution: handle undefined message in logUsedTokens --- src/execution.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/execution.ts b/src/execution.ts index 1cfcaa8..63679fa 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -172,12 +172,12 @@ export async function queueRequest(request: apiRequest) { * Logs used tokens to the terminal and to the database * @param answer the response that OpenAI returned * @param message the message that initiated the execution - * @param functionRan counter of how many function have been ran + * @param functionRan counter of how many function have been ran (to distinct records in database) */ function logUsedTokens( answer: ChatCompletion, - message: RequestMessage, - functionRan: number, + message: RequestMessage | undefined = undefined, + functionRan: number = 0, ) { const usage = answer.usage; const functionNames = @@ -185,6 +185,12 @@ function logUsedTokens( v => v.type === "function" ? v.function.name : `[unknown type]` ); if (usage !== undefined) { + if (!message) { + // log usage to stdout even if we can't store it in database + console.warn(`Used ${usage.total_tokens} (${usage.prompt_tokens} + ${usage.completion_tokens}) tokens from unknown call`); + // it doesn't make sense to store usage in database if we don't know where it came from + return; + } 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}${functionNames && functionNames.length > 0 ? " [Tools: " + functionNames.join(", ") + "]" : ""}`); @@ -197,7 +203,7 @@ function logUsedTokens( usageRequest: usage.prompt_tokens, usageResponse: usage.completion_tokens, functionName: functionNames?.join(", ") ?? null, - functionRan: functionNames ? functionRan : 0, + functionRan: functionRan, } }).catch((e => { console.error("Failed to push to a database"); From 482f72a4d12f85815f99eb0de89f132eb67185b3 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 04:03:34 +0200 Subject: [PATCH 32/39] execution: factor out chat completion process --- src/execution.ts | 65 +++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/execution.ts b/src/execution.ts index 63679fa..4010b51 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -219,7 +219,6 @@ function logUsedTokens( async function executeFromQueue(channel: string) { const channelQueue = channelsRunning.get(channel) as ChannelsRunningValue; const message = channelQueue.at(0) as RequestMessage; - let functionRanCounter = 0; let OpenAImessages: ChatCompletionMessageParam[] = []; // ignore if we can't even send anything to reply @@ -247,30 +246,7 @@ async function executeFromQueue(channel: string) { }); OpenAImessages = toOpenAIMessages(messages.values()); - let generatedMessage: ChatCompletionMessage | undefined = undefined; - let answer: Awaited>; - - do { - answer = await openai.chat.completions.create({ - ...config.chatCompletionParams, - messages: OpenAImessages, - // FIXME: don't use new instance of FunctionManager - tools: new FunctionManager().getToolsForOpenAi(), - }); - - functionRanCounter += answer.choices[0].message?.tool_calls?.length ?? 0; - logUsedTokens(answer, message, ++functionRanCounter); - - generatedMessage = answer.choices[0].message; - if (!generatedMessage) throw new Error("Empty message received"); - - // handle tool calls - if (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0) { - OpenAImessages.push(generatedMessage); - // FIXME: don't use new instance of FunctionManager - OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); - } - } while (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0); + const answer = await executeChatCompletion(OpenAImessages, message); channelQueue.stopTyping(); @@ -349,3 +325,42 @@ async function executeFromQueue(channel: string) { else return executeFromQueue(channel); } + +/** + * Executes the chat completion process. + * + * @param OpenAImessages An array of ChatCompletionMessageParam objects representing the messages for chat completion. + * @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. + */ +async function executeChatCompletion( + OpenAImessages: ChatCompletionMessageParam[], + message: RequestMessage | undefined, +) { + let generatedMessage: ChatCompletionMessage | undefined = undefined; + let answer: Awaited>; + let functionRanCounter = 0; + + do { + answer = await openai.chat.completions.create({ + ...config.chatCompletionParams, + messages: OpenAImessages, + // FIXME: don't use new instance of FunctionManager + tools: new FunctionManager().getToolsForOpenAi(), + }); + + functionRanCounter += answer.choices[0].message?.tool_calls?.length ?? 0; + logUsedTokens(answer, message, ++functionRanCounter); + + generatedMessage = answer.choices[0].message; + if (!generatedMessage) throw new Error("Empty message received"); + + // handle tool calls + if (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0) { + OpenAImessages.push(generatedMessage); + // FIXME: don't use new instance of FunctionManager + OpenAImessages.push(...(await new FunctionManager().handleToolCalls(generatedMessage.tool_calls))); + } + } while (generatedMessage.tool_calls !== undefined && generatedMessage.tool_calls.length > 0); + return answer; +} From 2fab1b1b428fa9fcd9b8c02e18cdb3423e2abd51 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 05:17:32 +0200 Subject: [PATCH 33/39] execution: factor out replying code to it's own fuction --- src/execution.ts | 49 ++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/execution.ts b/src/execution.ts index 4010b51..a78131f 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -252,26 +252,7 @@ async function executeFromQueue(channel: string) { const answerContent = answer.choices[0].message?.content; - if (answerContent === null || answerContent === "") { - if (message instanceof DiscordApi.Message) message.react("😶").catch(() => {/* GRACEFAIL: It's okay if the bot won't reply */}); - } - else { - const answerMessagesContent :string[] = [""]; - for (const i of answerContent.split(/\n\n/)) { - if (answerMessagesContent[answerMessagesContent.length-1].length + i.length < 2000) { - answerMessagesContent[answerMessagesContent.length-1] += "\n\n" + i; - } - else { - answerMessagesContent.push(i); - } - } - - for (const i of answerMessagesContent) { - const response = requestReply(message, {content: i}, {allowedMentions: { repliedUser: false }}); - - await response.then(rval => Moderation.checkMessageNoReturn(rval)); - } - } + await replyInMultiMessage(answerContent, message); } catch (e) { let errorText: string = ""; channelQueue.stopTyping(); @@ -326,6 +307,34 @@ async function executeFromQueue(channel: string) { return executeFromQueue(channel); } +/** + * Replies to a message and splits to multiple messages if needed. + * @param answerContent - The content of the answer. + * @param message - The request message to reply to. + */ +async function replyInMultiMessage(answerContent: string | null, message: RequestMessage) { + if (answerContent === null || answerContent === "") { + if (message instanceof DiscordApi.Message) message.react("😶").catch(() => { }); + } + else { + const answerMessagesContent: string[] = [""]; + for (const i of answerContent.split(/\n\n/)) { + if (answerMessagesContent[answerMessagesContent.length - 1].length + i.length < 2000) { + answerMessagesContent[answerMessagesContent.length - 1] += "\n\n" + i; + } + else { + answerMessagesContent.push(i); + } + } + + for (const i of answerMessagesContent) { + const response = requestReply(message, { content: i }, { allowedMentions: { repliedUser: false } }); + + await response.then(rval => Moderation.checkMessageNoReturn(rval)); + } + } +} + /** * Executes the chat completion process. * From 9f5dfefb31448839826bb5dc7010cd2ee2ce2920 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 05:38:41 +0200 Subject: [PATCH 34/39] execution: support for requests that don't have channel set Interactions initiated outside of servers where bot is don't have channel assigned --- src/configDefault.ts | 4 ++-- src/execution.ts | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/configDefault.ts b/src/configDefault.ts index 620a363..dcd4dd9 100644 --- a/src/configDefault.ts +++ b/src/configDefault.ts @@ -1,4 +1,3 @@ -import { Message } from "discord.js"; import { ChatCompletionMessageParam as OpenAIMessage, ChatCompletionCreateParamsNonStreaming as ChatCompletionRequestData, @@ -6,6 +5,7 @@ import { import IQuota from "./IQuota"; import MessageCount from "./quota/messageCount"; +import { apiRequest } from "./execution"; export interface IConfigRequired { /** Tokens to authentiate with */ @@ -14,7 +14,7 @@ export interface IConfigRequired { readonly OpenAI: string; }; /** Messages to append at the start of every chat history when sending to API */ - systemPrompt(context: Message): OpenAIMessage[]; + systemPrompt(context: apiRequest): OpenAIMessage[]; /** OpenAI model config */ readonly chatCompletionParams: Omit; /** Limits for message selection */ diff --git a/src/execution.ts b/src/execution.ts index a78131f..f715564 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -73,7 +73,7 @@ export function getAuthor(request: apiRequest) { * @returns Promise of the done action */ function requestReply( - request: RequestMessage, + request: apiRequest, message: DiscordApi.MessageReplyOptions & DiscordApi.InteractionReplyOptions, // TODO: add support for these below replyOptions: DiscordApi.MessageReplyOptions = {}, @@ -176,7 +176,7 @@ export async function queueRequest(request: apiRequest) { */ function logUsedTokens( answer: ChatCompletion, - message: RequestMessage | undefined = undefined, + message: apiRequest | undefined = undefined, functionRan: number = 0, ) { const usage = answer.usage; @@ -191,14 +191,17 @@ function logUsedTokens( // it doesn't make sense to store usage in database if we don't know where it came from return; } - 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}${functionNames && functionNames.length > 0 ? " [Tools: " + functionNames.join(", ") + "]" : ""}`); + const channelName: string = !message.channel ? "[No channel]" + : !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}${functionNames && functionNames.length > 0 ? " [Tools: " + functionNames.join(", ") + "]" : ""}`); database.usage.create({ data: { timestamp: message.createdAt, user: BigInt(getAuthor(message).id), - channel: BigInt(message.channelId), + channel: BigInt(message.channelId ?? 0), guild: message.guildId ? BigInt(message.guildId) : null, usageRequest: usage.prompt_tokens, usageResponse: usage.completion_tokens, @@ -312,7 +315,7 @@ async function executeFromQueue(channel: string) { * @param answerContent - The content of the answer. * @param message - The request message to reply to. */ -async function replyInMultiMessage(answerContent: string | null, message: RequestMessage) { +async function replyInMultiMessage(answerContent: string | null, message: apiRequest) { if (answerContent === null || answerContent === "") { if (message instanceof DiscordApi.Message) message.react("😶").catch(() => { }); } @@ -344,7 +347,7 @@ async function replyInMultiMessage(answerContent: string | null, message: Reques */ async function executeChatCompletion( OpenAImessages: ChatCompletionMessageParam[], - message: RequestMessage | undefined, + message: apiRequest | undefined, ) { let generatedMessage: ChatCompletionMessage | undefined = undefined; let answer: Awaited>; From 6efb6e587679cd678739a3f8ea1362f34c4b5e4f Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 05:41:07 +0200 Subject: [PATCH 35/39] commands/ask: create Allows to interact with the bot when bot is user installed in discord. --- src/commands/ask.ts | 74 +++++++++++++++++++++++++++++++++++++++++ src/execution.ts | 4 +-- src/toOpenAIMessages.ts | 2 +- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/commands/ask.ts diff --git a/src/commands/ask.ts b/src/commands/ask.ts new file mode 100644 index 0000000..ea39da7 --- /dev/null +++ b/src/commands/ask.ts @@ -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); + } +} diff --git a/src/execution.ts b/src/execution.ts index f715564..579a435 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -315,7 +315,7 @@ async function executeFromQueue(channel: string) { * @param answerContent - The content of the answer. * @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 (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. * @returns A Promise that resolves to the answer from the chat completion process. */ -async function executeChatCompletion( +export async function executeChatCompletion( OpenAImessages: ChatCompletionMessageParam[], message: apiRequest | undefined, ) { diff --git a/src/toOpenAIMessages.ts b/src/toOpenAIMessages.ts index f93d235..54ad00f 100644 --- a/src/toOpenAIMessages.ts +++ b/src/toOpenAIMessages.ts @@ -63,7 +63,7 @@ export function formatMessage(message: DiscordMessage): string { * @param name the name to format * @returns formatted name */ -function formatName(name: string): string { +export function formatName(name: string): string { // replace all characters to ascii equivelant return FoldToAscii.foldReplacing(name) // White spaces are not allowed From b1e464fe509413443dfcd6ce890afd7c3f43b329 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 06:14:57 +0200 Subject: [PATCH 36/39] Dockerfile: create db directory --- Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile b/Dockerfile index 52b9fb1..6386189 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,12 @@ RUN npx tsc # regardless of the user of the container RUN chmod 777 dist +# Create a db directory for sqlite database file +# it is required because in order to write to sqlite file +# the directory must be writable +RUN mkdir /db +RUN chmod 777 /db + # Run the app CMD ["node", "dist/src/index.js"] STOPSIGNAL SIGINT From 6f5f4251663152990d966c58755bbf97f6525dca Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 07:02:21 +0200 Subject: [PATCH 37/39] configDefault: add status options --- src/configDefault.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 1 + 2 files changed, 69 insertions(+) diff --git a/src/configDefault.ts b/src/configDefault.ts index dcd4dd9..130b1a2 100644 --- a/src/configDefault.ts +++ b/src/configDefault.ts @@ -1,3 +1,8 @@ +import { + ActivityType +, type PresenceStatusData +, type PresenceData +} from "discord.js"; import { ChatCompletionMessageParam as OpenAIMessage, ChatCompletionCreateParamsNonStreaming as ChatCompletionRequestData, @@ -13,6 +18,8 @@ export interface IConfigRequired { readonly Discord: string; readonly OpenAI: string; }; + /** Discord bot status */ + readonly status: PresenceData /** Messages to append at the start of every chat history when sending to API */ systemPrompt(context: apiRequest): OpenAIMessage[]; /** OpenAI model config */ @@ -39,6 +46,10 @@ export default function newConfig(config?: IConfig): IConfigRequired { return { ...defaultConfig, ...config }; } +function isEnvDefined(key: string): boolean { + return process.env[key] !== undefined; +} + function envAsString(key: string): string | undefined { key = key.toLocaleUpperCase(); return process.env[key]; @@ -50,6 +61,53 @@ function envAsNumber(key: string): number | undefined { return !Number.isNaN(value) ? value : undefined; } +function envAsBoolean(key: string): boolean | undefined { + key = key.toUpperCase(); + const value = process.env[key]; + return !(value === "false" || value === "0"); +} + +function envAsActivityType(key: string): ActivityType | undefined { + key = key.toUpperCase(); + const value = process.env[key]?.toUpperCase(); + switch (value) { + case "0": + case "PLAYING": + return ActivityType.Playing; + case "1": + case "STREAMING": + return ActivityType.Streaming; + case "2": + case "LISTENING": + return ActivityType.Listening; + case "3": + case "WATCHING": + return ActivityType.Watching; + case "4": + case "CUSTOM": + return ActivityType.Custom; + case "5": + case "COMPETING": + return ActivityType.Competing; + default: + return undefined; + } +} + +function envAsPresenceStatusData(key: string): PresenceStatusData | undefined { + key = key.toUpperCase(); + const value = process.env[key]?.toLowerCase(); + switch (value) { + case "online": + case "idle": + case "dnd": + case "invisible": + return value; + default: + return undefined; + } +} + const defaultConfig: IConfigRequired = { tokens: { Discord: envAsString("TOKENS__DISCORD") ?? "", @@ -65,6 +123,16 @@ const defaultConfig: IConfigRequired = { }, ]; }, + status: { + activities: isEnvDefined("STATUS__NAME") ? [{ + name: envAsString("STATUS__NAME") as string, + type: envAsActivityType("STATUS__TYPE") ?? ActivityType.Custom, + state: envAsString("STATUS__STATE"), + url: envAsString("STATUS__URL"), + }] : undefined, + status: envAsPresenceStatusData("STATUS__STATUS"), + afk: envAsBoolean("STATUS__AFK"), + }, chatCompletionParams: { model: envAsString("CHAT_COMPLETION_PARAMS__MODEL") ?? "gpt-3.5-turbo", max_tokens: envAsNumber("CHAT_COMPLETION_PARAMS__MAX_TOKENS") ?? 384, diff --git a/src/index.ts b/src/index.ts index eb7a9f7..38468b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -55,6 +55,7 @@ interactionManager.bindClient(discord); discord.on("ready", event => { console.log(`Connected to Discord as ${event.user.tag} (${event.user.id})`); + event.user.setPresence(config.status); }); discord.on("messageCreate", message => { From c4edf55f656ce0bb8ffe928c3f15e99124bfc94b Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 08:07:46 +0200 Subject: [PATCH 38/39] commands/ask: enforce userLimit --- src/commands/ask.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/commands/ask.ts b/src/commands/ask.ts index ea39da7..d5a1d30 100644 --- a/src/commands/ask.ts +++ b/src/commands/ask.ts @@ -56,7 +56,23 @@ export default class Ask extends Command implements Command { }); return; } - + + const userLimit = await config.quota.checkUser(interaction.user, interaction); + + if (userLimit.used >= userLimit.quota) { + interaction.reply({ + + embeds: [{ + color: 0xff0000, + description: "You've used up your quota,\n" + userLimit.toString(), + }], + ephemeral: true, + }).catch(e => { + console.error("Failed to reply to user: ", e); + }); + return; + } + // TODO: check content in moderation API const messages: ChatCompletionMessageParam[] = [ From 1b402c791ce8f4963f10cb8d8ac6919893ca6b22 Mon Sep 17 00:00:00 2001 From: Wroclaw Date: Fri, 26 Apr 2024 08:13:29 +0200 Subject: [PATCH 39/39] execution: log channel ID to terminal if it's unknown channelId is set for commands executed outside of common guilds no changes for usage logging in database is required --- src/execution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/execution.ts b/src/execution.ts index 579a435..8c550af 100644 --- a/src/execution.ts +++ b/src/execution.ts @@ -191,7 +191,8 @@ function logUsedTokens( // it doesn't make sense to store usage in database if we don't know where it came from return; } - const channelName: string = !message.channel ? "[No channel]" + const channelName: string = !message.channelId ? "[No channel]" + : !message.channel ? `[Unknown channel: ${message.channelId}]` : !message.channel.isDMBased() ? `#${message.channel.name} (${message.guild?.name})` : `#@${getAuthor(message).tag}` ;