diff --git a/commands/message/core/help.js b/commands/message/core/help.js index 5214d46..9aa8a8b 100644 --- a/commands/message/core/help.js +++ b/commands/message/core/help.js @@ -7,7 +7,6 @@ const { paginator } = require('../../../labscore/client'); const { editOrReply } = require('../../../labscore/utils/message'); const { Permissions } = require("detritus-client/lib/constants"); -const { canUseLimitedTestCommands } = require('../../../labscore/utils/testing'); function createHelpPage(context, title, contents, descriptions) { return page(createEmbed("default", context, { @@ -109,7 +108,7 @@ module.exports = { }, permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - if (canUseLimitedTestCommands(context)) categories["limited"] = `${iconPill("stars", "Limited Test Commands")}`; + if(await hasFeature(context, "core/help")) categories["limited"] = `${iconPill("stars", "Limited Test Commands")}`; else if (categories["limited"]) delete categories["limited"] if (args.command) { diff --git a/commands/message/dev/refresh-configs.js b/commands/message/dev/refresh-configs.js new file mode 100644 index 0000000..e5964bf --- /dev/null +++ b/commands/message/dev/refresh-configs.js @@ -0,0 +1,21 @@ +const { createEmbed } = require("../../../labscore/utils/embed"); +const { editOrReply } = require("../../../labscore/utils/message"); +const { getTestConfig } = require("../../../labscore/utils/testing"); + +module.exports = { + name: "refresh-configs", + metadata: { + description: 'Reload configs.', + description_short: 'Reload configs.', + examples: ['refresh-configs'], + category: 'dev', + usage: 'refresh-configs' + }, + onBefore: context => context.user.isClientOwner, + onCancel: ()=>{}, + run: async (context, args) => { + await context.triggerTyping(); + let c = await getTestConfig(); + return await editOrReply(context, createEmbed("success", context, "Refreshed configs (v"+c.revision+").")); + } +}; \ No newline at end of file diff --git a/commands/message/genai/gemini-vision.js b/commands/message/genai/gemini-vision.js index a692d23..73100d6 100644 --- a/commands/message/genai/gemini-vision.js +++ b/commands/message/genai/gemini-vision.js @@ -9,7 +9,7 @@ const { Permissions } = require("detritus-client/lib/constants"); const superagent = require('superagent'); const { STATIC_ICONS } = require("../../../labscore/utils/statics"); const { stringwrap, iconPill, smallIconPill } = require("../../../labscore/utils/markdown"); -const { canUseLimitedTestCommands } = require("../../../labscore/utils/testing"); +const { hasFeature } = require("../../../labscore/utils/testing"); module.exports = { name: 'gemini-vision', label: 'text', @@ -23,8 +23,7 @@ module.exports = { }, permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.ATTACH_FILES, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - context.triggerTyping(); - if(!canUseLimitedTestCommands(context)) return; + if(!await hasFeature(context, "ai/gemini/vision")) return; context.triggerTyping(); // for the sake of privacy, make the context window one message diff --git a/commands/message/genai/gemini.js b/commands/message/genai/gemini.js index 121082a..5491309 100644 --- a/commands/message/genai/gemini.js +++ b/commands/message/genai/gemini.js @@ -6,7 +6,7 @@ const { Permissions } = require("detritus-client/lib/constants"); const { STATIC_ICONS } = require("../../../labscore/utils/statics"); const { stringwrap, iconPill, smallIconPill } = require("../../../labscore/utils/markdown"); -const { canUseLimitedTestCommands } = require("../../../labscore/utils/testing"); +const { hasFeature } = require("../../../labscore/utils/testing"); module.exports = { name: 'gemini', label: 'text', @@ -20,8 +20,7 @@ module.exports = { }, permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.ATTACH_FILES, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - context.triggerTyping(); - if(!canUseLimitedTestCommands(context)) return; + if(!await hasFeature(context, "ai/gemini/text")) return; context.triggerTyping(); if(!args.text) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (text).`)) diff --git a/commands/message/limited/bard.js b/commands/message/limited/bard.js index 8208c5b..f1598d5 100644 --- a/commands/message/limited/bard.js +++ b/commands/message/limited/bard.js @@ -1,7 +1,6 @@ const { createEmbed } = require('../../../labscore/utils/embed') const { editOrReply } = require('../../../labscore/utils/message') -const { canUseLimitedTestCommands } = require('../../../labscore/utils/testing') const { STATIC_ICONS } = require('../../../labscore/utils/statics'); const superagent = require('superagent') @@ -10,6 +9,7 @@ const { iconPill, stringwrap } = require('../../../labscore/utils/markdown') const { Permissions, InteractionCallbackTypes } = require("detritus-client/lib/constants"); const { Components } = require('detritus-client/lib/utils'); const { bard } = require('../../../labscore/api/obelisk'); +const { hasFeature } = require('../../../labscore/utils/testing'); module.exports = { name: 'bard', @@ -24,7 +24,7 @@ module.exports = { args: [], permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.ATTACH_FILES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - if(!canUseLimitedTestCommands(context)) return; + if(!await hasFeature(context, "ai/bard")) return; context.triggerTyping(); if(!args.text) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (text).`)) diff --git a/commands/message/limited/disstrack.js b/commands/message/limited/disstrack.js deleted file mode 100644 index 6a6209e..0000000 --- a/commands/message/limited/disstrack.js +++ /dev/null @@ -1,45 +0,0 @@ -const { createEmbed } = require('../../../labscore/utils/embed') -const { editOrReply } = require('../../../labscore/utils/message') - -const superagent = require('superagent') -const { codeblock, iconPill, smallIconPill } = require('../../../labscore/utils/markdown') - -const { Permissions } = require("detritus-client/lib/constants"); -const { canUseLimitedTestCommands } = require('../../../labscore/utils/testing') -const { STATICS } = require('../../../labscore/utils/statics'); -const { chatgpt } = require('../../../labscore/api/obelisk'); - -module.exports = { - name: 'disstrack', - label: 'text', - metadata: { - description: `${iconPill("generative_ai", "LIMITED TESTING")}\n\nAI Generated Disstracks, powered by ChatGPT`, - description_short: 'AI generated disstracks.', - examples: ['disstrack'], - category: 'limited', - usage: 'disstrack ' - }, - permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], - run: async (context, args) => { - if(!canUseLimitedTestCommands(context)) return; - context.triggerTyping(); - if(!args.text) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (text).`)) - try{ - await editOrReply(context, createEmbed("ai", context, "Spitting bars...")) - - let res = await chatgpt(context, "Write a disstrack about the subject the user supplies. The disstrack should have at least one verse and a chorus.", args.text); - res = res.response; - - return editOrReply(context, createEmbed("default", context, { - description: smallIconPill("generative_ai", args.text) + '\n' + codeblock("ansi", [res.body.output.substr(0, 2020 - args.text.length)]), - footer: { - text: `Generative AI is experimental. • ${context.application.name}`, - iconUrl: STATICS.openai - } - })) - }catch(e){ - console.log(e) - return editOrReply(context, createEmbed("error", context, `Unable to generate text.`)) - } - } -}; \ No newline at end of file diff --git a/commands/message/limited/palm.js b/commands/message/limited/palm.js index 05c7aad..f481696 100644 --- a/commands/message/limited/palm.js +++ b/commands/message/limited/palm.js @@ -1,7 +1,6 @@ const { createEmbed } = require('../../../labscore/utils/embed') const { editOrReply } = require('../../../labscore/utils/message') -const { canUseLimitedTestCommands, isLimitedTestUser } = require('../../../labscore/utils/testing') const { STATIC_ICONS } = require('../../../labscore/utils/statics'); const superagent = require('superagent') @@ -9,6 +8,7 @@ const { iconPill, stringwrap, smallIconPill } = require('../../../labscore/utils const { Permissions } = require("detritus-client/lib/constants"); const { palm2 } = require('../../../labscore/api/obelisk'); +const { hasFeature } = require('../../../labscore/utils/testing'); module.exports = { name: 'palm', @@ -27,7 +27,7 @@ module.exports = { ], permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.ATTACH_FILES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - if(!canUseLimitedTestCommands(context)) return; + if(!await hasFeature(context, "ai/palm")) return; context.triggerTyping(); if(!args.text) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (text).`)) diff --git a/commands/message/limited/summarize.js b/commands/message/limited/summarize.js index 4787355..d5a0f8f 100644 --- a/commands/message/limited/summarize.js +++ b/commands/message/limited/summarize.js @@ -4,9 +4,9 @@ const { editOrReply } = require('../../../labscore/utils/message') const { iconPill, smallIconPill } = require('../../../labscore/utils/markdown') const { Permissions } = require("detritus-client/lib/constants"); -const { canUseLimitedTestCommands } = require('../../../labscore/utils/testing') const { STATIC_ICONS } = require('../../../labscore/utils/statics'); const { summarizeWebpage } = require('../../../labscore/api/obelisk'); +const { hasFeature } = require('../../../labscore/utils/testing'); const URL_REGEX = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([^> \n]*)/ @@ -23,7 +23,7 @@ module.exports = { }, permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], run: async (context, args) => { - if(!canUseLimitedTestCommands(context)) return; + if(!await hasFeature(context, "flamingo/summary")) return; context.triggerTyping(); let content = args.text; diff --git a/labscore/utils/testing.js b/labscore/utils/testing.js index 632eece..0d40ae7 100644 --- a/labscore/utils/testing.js +++ b/labscore/utils/testing.js @@ -1,37 +1,57 @@ +const superagent = require('superagent'); -// Get Test Config -let LIMITED_TEST_GUILDS; -if(process.env.TESTING_SERVER_IDS) LIMITED_TEST_GUILDS = process.env.TESTING_SERVER_IDS.split(';') -let LIMITED_TEST_CHANNELS; -if(process.env.TESTING_CHANNEL_IDS) LIMITED_TEST_CHANNELS = process.env.TESTING_CHANNEL_IDS.split(';') -let LIMITED_TEST_USERS; -if(process.env.TESTING_USER_IDS) LIMITED_TEST_USERS = process.env.TESTING_USER_IDS.split(';') +let TESTING_REVISION = "-1"; -function isLimitedTestGuild(guild){ - if(LIMITED_TEST_GUILDS && LIMITED_TEST_GUILDS.includes(guild.id)) return true; +let TESTING_GROUPS = {} +let TESTING_ASSIGNMENTS = {} + +function validateGroup(groups = [], featureId){ + for(const g of groups){ + if(TESTING_GROUPS[g] && TESTING_GROUPS[g].includes(featureId)) return true; + if(TESTING_GROUPS[g] && TESTING_GROUPS[g].includes("*")) return true; + } return false; } -function isLimitedTestChannel(channel){ - if(LIMITED_TEST_CHANNELS && LIMITED_TEST_CHANNELS.includes(channel.id)) return true; - return false; +// Fetches the testing configuration from the cdn +async function getTestConfig(){ + //if(!process.env.TESTING_CONFIG_URL) throw "Missing TESTING_CONFIG_URL in environment"; + + try{ + let config = await superagent.get(process.env.TESTING_CONFIG_URL) + .query({ + _t: Date.now() + }); + + TESTING_GROUPS = config.body.feature_groups + TESTING_ASSIGNMENTS = config.body.feature_assignments + TESTING_REVISION = config.body.revision + + console.log('Loaded test configs (revision ' + TESTING_REVISION + ')') + + return config.body; + }catch(e){ + throw "Unable to retrieve test config." + } } -function isLimitedTestUser(user){ - if(LIMITED_TEST_USERS && LIMITED_TEST_USERS.includes(user.id)) return true; - return false; -} +async function hasFeature(context, feature){ + // We need to load the test config first + if(TESTING_REVISION == "-1") await getTestConfig(); + + // Server + if(context.guild && TESTING_ASSIGNMENTS.servers) if(validateGroup(TESTING_ASSIGNMENTS.servers[context.guild.id], feature)) return true; + // Channel + if(context.channel && TESTING_ASSIGNMENTS.channels) if(validateGroup(TESTING_ASSIGNMENTS.channels[context.channel.id], feature)) return true; + // Category + if(context.channel && context.channel.parent_id && TESTING_ASSIGNMENTS.categories) if(validateGroup(TESTING_ASSIGNMENTS.categories[context.channel.parent_id], feature)) return true; + // User + if(context.user && TESTING_ASSIGNMENTS.users) if(validateGroup(TESTING_ASSIGNMENTS.users[context.user.id], feature)) return true; -function canUseLimitedTestCommands(context){ - if(isLimitedTestGuild(context.guild)) return true; - if(isLimitedTestChannel(context.channel)) return true; - if(isLimitedTestUser(context.user)) return true; return false; } module.exports = { - canUseLimitedTestCommands, - isLimitedTestGuild, - isLimitedTestChannel, - isLimitedTestUser + getTestConfig, + hasFeature } \ No newline at end of file