diff --git a/commands/message/fun/ask.js b/commands/message/fun/ask.js deleted file mode 100644 index 614621e..0000000 --- a/commands/message/fun/ask.js +++ /dev/null @@ -1,38 +0,0 @@ -const { createEmbed } = require('../../../labscore/utils/embed') -const { format } = require('../../../labscore/utils/ansi') -const { editOrReply } = require('../../../labscore/utils/message') - -const superagent = require('superagent') -const { codeblock } = require('../../../labscore/utils/markdown') - -const { Permissions } = require("detritus-client/lib/constants"); - -module.exports = { - name: 'ask', - label: 'text', - metadata: { - description: 'Ask AI questions. May not be accurate.', - description_short: 'AI questions', - examples: ['ask How many otter species are there?'], - category: 'broken', - usage: 'ask ' - }, - permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], - run: async (context, args) => { - return; - context.triggerTyping(); - if (!args.text) return editOrReply(context, createEmbed("warning", context, `Missing Parameter (text).`)) - try { - let res = await superagent.get(`${process.env.AI_SERVER}/ask`) - .query({ - prompt: args.text - }) - return editOrReply(context, createEmbed("default", context, { - description: codeblock("ansi", [format(args.text, "cyan") + res.body.text]) - })) - } 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/ask.js b/commands/message/limited/ask.js new file mode 100644 index 0000000..1a3c1c3 --- /dev/null +++ b/commands/message/limited/ask.js @@ -0,0 +1,77 @@ +const { createEmbed } = require('../../../labscore/utils/embed') +const { editOrReply } = require('../../../labscore/utils/message') + +const { iconPill, smallIconPill } = require('../../../labscore/utils/markdown') + +const { Permissions } = require("detritus-client/lib/constants"); +const { STATIC_ICONS } = require('../../../labscore/utils/statics'); +const { webAsk } = 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]*)/ + +module.exports = { + name: 'ask', + label: 'text', + metadata: { + description: `${iconPill("generative_ai", "LIMITED TESTING")}\n${smallIconPill("reply", "Supports Replies")}\n\nAsk questions about web pages and videos. You have to **reply** to a message or embed containing a link to ask questions about it.`, + description_short: 'Website summaries.', + examples: ['ask why do they call it oven when you of in the cold food of out hot eat the food'], + category: 'limited', + usage: 'ask ' + }, + permissionsClient: [Permissions.EMBED_LINKS, Permissions.SEND_MESSAGES, Permissions.USE_EXTERNAL_EMOJIS, Permissions.READ_MESSAGE_HISTORY], + run: async (context, args) => { + if(!await hasFeature(context, "flamingo/summary")) return; + context.triggerTyping(); + + if(!args.text) return editOrReply(context, createEmbed("warning", context, "You need to ask a question.")) + if(!context.message.messageReference) return editOrReply(context, createEmbed("warning", context, "You need to reply to a message containing a link.")) + + let msg = await context.message.channel.fetchMessage(context.message.messageReference.messageId); + + if(msg.content && msg.content.length) content = msg.content + else if(msg.embeds?.length) for(const e of msg.embeds){ + if(e[1].description?.length) content = e[1].description; + if(e[1].author?.url) content = e[1].author?.url; + if(e[1].url) content = e[1].url + } + + let webUrl = content.match(URL_REGEX) + if(!webUrl) return editOrReply(context, createEmbed("warning", context, `No URLs found.`)) + try{ + await editOrReply(context, createEmbed("ai_custom", "Generating response...", STATIC_ICONS.ai_summary)) + + let res = await webAsk(context, webUrl[0], args.text) + if(!res.response.body.response) return editOrReply(context, createEmbed("error", context, "Unable to generate answer. Try again later.")) + + let description = ""; + let files = []; + if(res.response.body.response.length <= 4000) description = res.response.body.response + else { + files.push({ + filename: `ask.${Date.now().toString(36)}.txt`, + value: Buffer.from(res.response.body.response) + }) + } + + return editOrReply(context, { + embeds: [createEmbed("defaultNoFooter", context, { + author: { + iconUrl: STATIC_ICONS.ai_summary, + name: res.response.body.title || 'Answer from the page', + url: webUrl[0] + }, + description, + footer: { + text: "Generative AI is experimental. Response may be factually wrong or completely made up." + } + })], + files + }) + }catch(e){ + console.log(e) + return editOrReply(context, createEmbed("error", context, e.response.body.message)) + } + } +}; \ No newline at end of file diff --git a/labscore/api/obelisk/endpoints.js b/labscore/api/obelisk/endpoints.js index 10b9e4f..0d1535d 100644 --- a/labscore/api/obelisk/endpoints.js +++ b/labscore/api/obelisk/endpoints.js @@ -14,6 +14,7 @@ const ObeliskApi = Object.freeze({ OPENAI_CHATGPT: "/parrot/v1/openai:chatgpt", OPENAI_GPT4: "/parrot/v1/openai:gpt4", + WEB_ASK: "/flamingo/v1/web:ask", SUMMARIZE_WEBPAGES: "/flamingo/v1/web:summarize", AI_WALLPAPER: "/robin/v1/wallpaper:generate", diff --git a/labscore/api/obelisk/index.js b/labscore/api/obelisk/index.js index 94c0c5a..9270198 100644 --- a/labscore/api/obelisk/index.js +++ b/labscore/api/obelisk/index.js @@ -82,6 +82,13 @@ module.exports.gpt4 = async function(context, prompt, input){ } // FLAMINGO +module.exports.webAsk = async function(context, url, prompt){ + return await request(ObeliskApi.WEB_ASK, "POST", {}, { + url, + prompt + }) +} + module.exports.summarizeWebpage = async function(context, url){ return await request(ObeliskApi.SUMMARIZE_WEBPAGES, "POST", {}, { url