From 53cce2ade1c85f0197f7cd8c00a73db4ed302bf1 Mon Sep 17 00:00:00 2001 From: mekb Date: Mon, 22 Apr 2024 19:55:59 +1000 Subject: [PATCH 1/8] :memo: Archive project --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f742f03..c0d3fd4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@

Discord chat with the bot

+### Archived +I have decided to archive this project as I no longer have the time to maintain it. If you would like to take over the project, [please let me know](https://github.com/mekb-turtle). + ### Set-up instructions 1. Install [Node.js](https://nodejs.org) (if you have a package manager, use that instead to install this) - Make sure to install at least v14 of Node.js From 21fadef022bf67474814418647816148a9f862fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20J=C4=99drzejewski?= <46965900+238SAMIxD@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:06:52 +0200 Subject: [PATCH 2/8] Add Stable Diffusion --- .env.example | 3 ++ .gitignore | 1 + README.md | 4 +- src/bot.js | 111 ++++++++++++++++++++++++++++++++++++++- src/commands/commands.js | 3 ++ src/commands/text2img.js | 56 ++++++++++++++++++++ 6 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 src/commands/commands.js create mode 100644 src/commands/text2img.js diff --git a/.env.example b/.env.example index 5f175ff..dc2681a 100644 --- a/.env.example +++ b/.env.example @@ -7,6 +7,9 @@ MODEL=orca # Ollama URL (if you want to use multiple, separate them by commas) OLLAMA=http://localhost:11434 +# Stable diffusion URL +STABLE_DIFFUSION=http://localhost:7860 + # What Discord channels to enable it in (by ID) CHANNELS=123456789,987654321 diff --git a/.gitignore b/.gitignore index 553aeb5..0d51cca 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ pnpm-lock.yaml pnpm-lock.yml node_modules/ .env +.vscode/ diff --git a/README.md b/README.md index c0d3fd4..bf0e817 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Discord AI Bot

-

Discord bot to interact with Ollama as a chatbot

+

Discord bot to interact with Ollama and AUTOMATIC1111 Stable Diffusion as a chatbot

Stars

Discord chat with the bot

@@ -34,6 +34,8 @@ I have decided to archive this project as I no longer have the time to maintain - You can edit the system message the bot uses, or disable it entirely 8. Start the bot with `npm start` 9. You can interact with the bot by @mentioning it with your message +10. Install Stable Diffusion +11. Run the script `./webui.sh --api --listen` ### Set-up instructions with Docker 1. Install [Docker](https://docs.docker.com/get-docker/) diff --git a/src/bot.js b/src/bot.js index 7752304..714e5d0 100644 --- a/src/bot.js +++ b/src/bot.js @@ -1,12 +1,22 @@ -import { Client, Events, GatewayIntentBits, MessageType, Partials } from "discord.js"; +import { + Client, + Events, + GatewayIntentBits, + MessageType, + Partials, + REST, + Routes, +} from "discord.js"; import { Logger, LogLevel } from "meklog"; import dotenv from "dotenv"; import axios from "axios"; +import commands from "./commands/commands.js"; dotenv.config(); const model = process.env.MODEL; const servers = process.env.OLLAMA.split(",").map(url => ({ url: new URL(url), available: true })); +const stableDiffusionServers = process.env.STABLE_DIFFUSION.split(",").map( url => ({ url: new URL(url), available: true })); const channels = process.env.CHANNELS.split(","); if (servers.length == 0) { @@ -82,6 +92,48 @@ async function makeRequest(path, method, data) { throw error; } +async function makeStableDiffusionRequest(path, method, data) { + while (stableDiffusionServers.filter(server => server.available).length == 0) { + // wait until a server is available + await new Promise(res => setTimeout(res, 1000)); + } + + let error = null; + // randomly loop through the servers available, don't shuffle the actual array because we want to be notified of any updates + let order = new Array(stableDiffusionServers.length).fill().map((_, i) => i); + if (randomServer) order = shuffleArray(order); + for (const j in order) { + if (!order.hasOwnProperty(j)) continue; + const i = order[j]; + // try one until it succeeds + try { + // make a request to stable diffusion + if (!stableDiffusionServers[i].available) continue; + const url = new URL(stableDiffusionServers[i].url); // don't modify the original URL + + stableDiffusionServers[i].available = false; + + if (path.startsWith("/")) path = path.substring(1); + if (!url.pathname.endsWith("/")) url.pathname += "/"; // safety + url.pathname += path; + log(LogLevel.Debug, `Making stable diffusion request to ${url}`); + const result = await axios({ + method, url, data + }); + stableDiffusionServers[i].available = true; + return result.data; + } catch (err) { + stableDiffusionServers[i].available = true; + error = err; + logError(error); + } + } + if (!error) { + throw new Error("No servers available"); + } + throw error; +} + const client = new Client({ intents: [ GatewayIntentBits.Guilds, @@ -96,9 +148,16 @@ const client = new Client({ ] }); +const rest = new REST({ version: "10" }).setToken(process.env.TOKEN); + client.once(Events.ClientReady, async () => { await client.guilds.fetch(); client.user.setPresence({ activities: [], status: "online" }); + await rest.put(Routes.applicationCommands(client.user.id), { + body: commands, + }); + + log(LogLevel.Info, "Successfully reloaded application slash (/) commands."); }); const messages = {}; @@ -160,7 +219,7 @@ function getBoolean(str) { } function parseJSONMessage(str) { - return str.split(/[\r\n]+/g).map(function(line) { + return str.split(/[\r\n]+/g).map(line => { const result = JSON.parse(`"${line}"`); if (typeof result !== "string") throw new "Invalid syntax in .env file"; return result; @@ -431,4 +490,52 @@ client.on(Events.MessageCreate, async message => { } }); +client.on(Events.InteractionCreate, async (interaction) => { + if (!interaction.isCommand()) return; + + const { commandName, options } = interaction; + + switch (commandName) { + case "text2img": + try { + const prompt = options.getString("prompt"); + const width = options.getNumber("width") || 256; + const height = options.getNumber("height") || 256; + const steps = options.getNumber("steps") || 10; + const batch_count = options.getNumber("batch_count") || 1; + const batch_size = options.getNumber("batch_size") || 1; + const enhance_prompt = (options.getBoolean("enhance_prompt") || true) ? "yes" : "no"; + + await interaction.deferReply(); + let stableDiffusionResponse = await makeStableDiffusionRequest( + "/sdapi/v1/txt2img", + "post", + { + prompt, + width, + height, + steps, + num_inference_steps: steps, + batch_count, + batch_size, + enhance_prompt, + } + ); + const images = stableDiffusionResponse.images.map((image) => + Buffer.from(image, "base64") + ); + await interaction.editReply({ + content: `Here are images from prompt \`${prompt}\``, + files: images, + }); + } catch (error) { + logError(error); + await interaction.editReply({ + content: "Error, please check the console", + }); + } + break; + } +}); + client.login(process.env.TOKEN); diff --git a/src/commands/commands.js b/src/commands/commands.js new file mode 100644 index 0000000..01edf15 --- /dev/null +++ b/src/commands/commands.js @@ -0,0 +1,3 @@ +import text2img from "./text2img.js"; + +export default [text2img]; diff --git a/src/commands/text2img.js b/src/commands/text2img.js new file mode 100644 index 0000000..c8f6097 --- /dev/null +++ b/src/commands/text2img.js @@ -0,0 +1,56 @@ +import { SlashCommandBuilder } from "discord.js"; + +const text2img = new SlashCommandBuilder() + .setName("text2img") + .setDescription("Convert text to image") + .addStringOption((option) => + option.setName("prompt").setDescription("Text to convert").setRequired(true) + ) + .addNumberOption((option) => + option + .setName("width") + .setDescription("Width of the image") + .setRequired(false) + .setMinValue(128) + .setMaxValue(1024) + ) + .addNumberOption((option) => + option + .setName("height") + .setDescription("Height of the image") + .setRequired(false) + .setMinValue(128) + .setMaxValue(1024) + ) + .addNumberOption((option) => + option + .setName("steps") + .setDescription("Number of steps") + .setRequired(false) + .setMinValue(5) + .setMaxValue(20) + ) + .addNumberOption((option) => + option + .setName("batch_count") + .setDescription("Batch count") + .setRequired(false) + .setMinValue(1) + .setMaxValue(4) + ) + .addNumberOption((option) => + option + .setName("batch_size") + .setDescription("Batch size") + .setRequired(false) + .setMinValue(1) + .setMaxValue(5) + ) + .addBooleanOption((option) => + option + .setName("enhance_prompt") + .setDescription("Enhance prompt") + .setRequired(false) + ); + +export default text2img; From ee905517ac4ad4585d11453ace90819e928e0075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20J=C4=99drzejewski?= <46965900+238SAMIxD@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:51:08 +0200 Subject: [PATCH 3/8] ESLint migration --- .eslintrc.json | 1 - eslint.config.mjs | 99 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 +++- src/bot.js | 40 +++++++++++-------- 4 files changed, 130 insertions(+), 18 deletions(-) create mode 100644 eslint.config.mjs diff --git a/.eslintrc.json b/.eslintrc.json index 12dcd8e..c652c3b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,7 +25,6 @@ "no-empty": "warn", "no-empty-function": "error", "no-floating-decimal": "error", - "no-inline-comments": "error", "no-lonely-if": "error", "no-multi-spaces": "error", "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..6ca2cbc --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,99 @@ +import globals from "globals"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}); + +export default [...compat.extends("eslint:recommended"), { + languageOptions: { + globals: { + ...globals.node + }, + + ecmaVersion: 2021, + sourceType: "module" + }, + + rules: { + "arrow-spacing": ["warn", { + before: true, + after: true + }], + + "brace-style": ["error", "1tbs", { + allowSingleLine: true + }], + + "comma-dangle": ["error", "never"], + "comma-spacing": "error", + "comma-style": "error", + curly: ["error", "multi-line", "consistent"], + "dot-location": ["error", "property"], + "handle-callback-err": "off", + + indent: ["error", "tab", { + SwitchCase: 1 + }], + + "keyword-spacing": "error", + + "max-nested-callbacks": ["error", { + max: 4 + }], + + "max-statements-per-line": ["error", { + max: 2 + }], + + "no-console": "off", + "no-empty": "warn", + "no-empty-function": "error", + "no-floating-decimal": "error", + "no-lonely-if": "error", + "no-multi-spaces": "error", + + "no-multiple-empty-lines": ["error", { + max: 2, + maxEOF: 1, + maxBOF: 0 + }], + + "no-shadow": ["error", { + allow: ["err", "resolve", "reject"] + }], + + "no-trailing-spaces": ["error"], + "no-var": "error", + "object-curly-spacing": ["error", "always"], + "prefer-const": "error", + quotes: ["error", "double"], + semi: ["error", "always"], + "space-before-blocks": "error", + + "space-before-function-paren": ["error", { + anonymous: "never", + named: "never", + asyncArrow: "always" + }], + + "space-in-parens": "error", + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "error", + yoda: "error", + "default-case-last": "error", + + "switch-colon-spacing": ["error", { + after: true, + before: false + }] + } +}]; \ No newline at end of file diff --git a/package.json b/package.json index d2d148e..8b679e5 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,11 @@ "dotenv": "^16.3.1", "meklog": "^1.0.2" }, - "type": "module" + "type": "module", + "devDependencies": { + "@eslint/js": "^9.7.0", + "@types/eslint__js": "^8.42.3", + "eslint": "^9.7.0", + "globals": "^15.8.0" + } } diff --git a/src/bot.js b/src/bot.js index 714e5d0..1bb3d84 100644 --- a/src/bot.js +++ b/src/bot.js @@ -5,7 +5,7 @@ import { MessageType, Partials, REST, - Routes, + Routes } from "discord.js"; import { Logger, LogLevel } from "meklog"; import dotenv from "dotenv"; @@ -16,7 +16,7 @@ dotenv.config(); const model = process.env.MODEL; const servers = process.env.OLLAMA.split(",").map(url => ({ url: new URL(url), available: true })); -const stableDiffusionServers = process.env.STABLE_DIFFUSION.split(",").map( url => ({ url: new URL(url), available: true })); +const stableDiffusionServers = process.env.STABLE_DIFFUSION.split(",").map(url => ({ url: new URL(url), available: true })); const channels = process.env.CHANNELS.split(","); if (servers.length == 0) { @@ -154,7 +154,7 @@ client.once(Events.ClientReady, async () => { await client.guilds.fetch(); client.user.setPresence({ activities: [], status: "online" }); await rest.put(Routes.applicationCommands(client.user.id), { - body: commands, + body: commands }); log(LogLevel.Info, "Successfully reloaded application slash (/) commands."); @@ -243,7 +243,7 @@ const useInitialPrompt = getBoolean(process.env.USE_INITIAL_PROMPT) && !!initial const requiresMention = getBoolean(process.env.REQUIRES_MENTION); async function replySplitMessage(replyMessage, content) { - const responseMessages = splitText(content, 2000).map(content => ({ content })); + const responseMessages = splitText(content, 2000).map(text => ({ content: text })); const replyMessages = []; for (let i = 0; i < responseMessages.length; ++i) { @@ -311,7 +311,7 @@ client.on(Events.MessageCreate, async message => { // deal with commands first before passing to LLM let userInput = message.content - .replace(new RegExp("^\s*" + myMention.source, ""), "").trim(); + .replace(new RegExp("^s*" + myMention.source, ""), "").trim(); // may change this to slash commands in the future // i'm using regular text commands currently because the bot interacts with text content anyway @@ -350,11 +350,16 @@ client.on(Events.MessageCreate, async message => { break; case "ping": // get ms difference - const beforeTime = Date.now(); - const reply = await message.reply({ content: "Ping" }); - const afterTime = Date.now(); - const difference = afterTime - beforeTime; - await reply.edit({ content: `Ping: ${difference}ms` }); + try { + const beforeTime = Date.now(); + const reply = await message.reply({ content: "Ping" }); + const afterTime = Date.now(); + const difference = afterTime - beforeTime; + await reply.edit({ content: `Ping: ${difference}ms` }); + } catch (error) { + logError(error); + await message.reply({ content: "Error, please check the console" }); + } break; case "": break; @@ -411,6 +416,7 @@ client.on(Events.MessageCreate, async message => { try { await message.channel.sendTyping(); } catch (error) { + logError(error); if (typingInterval != null) { clearInterval(typingInterval); } @@ -484,7 +490,9 @@ client.on(Events.MessageCreate, async message => { try { // return error await message.reply({ content: "Error, please check the console" }); - } catch (ignored) {} + } catch (ignored) { + logError(ignored); + } } logError(error); } @@ -504,10 +512,10 @@ client.on(Events.InteractionCreate, async (interaction) => { const steps = options.getNumber("steps") || 10; const batch_count = options.getNumber("batch_count") || 1; const batch_size = options.getNumber("batch_size") || 1; - const enhance_prompt = (options.getBoolean("enhance_prompt") || true) ? "yes" : "no"; + const enhance_prompt = (options.getBoolean("enhance_prompt") && true) ? "yes" : "no"; await interaction.deferReply(); - let stableDiffusionResponse = await makeStableDiffusionRequest( + const stableDiffusionResponse = await makeStableDiffusionRequest( "/sdapi/v1/txt2img", "post", { @@ -518,7 +526,7 @@ client.on(Events.InteractionCreate, async (interaction) => { num_inference_steps: steps, batch_count, batch_size, - enhance_prompt, + enhance_prompt } ); const images = stableDiffusionResponse.images.map((image) => @@ -526,12 +534,12 @@ client.on(Events.InteractionCreate, async (interaction) => { ); await interaction.editReply({ content: `Here are images from prompt \`${prompt}\``, - files: images, + files: images }); } catch (error) { logError(error); await interaction.editReply({ - content: "Error, please check the console", + content: "Error, please check the console" }); } break; From 6af49234afdfa5d6912cada8fe9ec4e06b6929ac Mon Sep 17 00:00:00 2001 From: mekb Date: Thu, 25 Jul 2024 07:52:23 +0000 Subject: [PATCH 4/8] :memo: Add disclaimer new maintained Add missing `npm i` step --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bf0e817..a41c5f1 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@

Discord chat with the bot

-### Archived -I have decided to archive this project as I no longer have the time to maintain it. If you would like to take over the project, [please let me know](https://github.com/mekb-turtle). +### New Maintainer +This repository is no longer being developed on by me, [mekb-turtle](https://github.com/mekb-turtle). ### Set-up instructions 1. Install [Node.js](https://nodejs.org) (if you have a package manager, use that instead to install this) @@ -32,10 +32,11 @@ I have decided to archive this project as I no longer have the time to maintain 1. In Discord, go to User Settings » Advanced, and enable Developer Mode 2. Right click on a channel you want to use, and click Copy Channel ID - You can edit the system message the bot uses, or disable it entirely -8. Start the bot with `npm start` -9. You can interact with the bot by @mentioning it with your message -10. Install Stable Diffusion -11. Run the script `./webui.sh --api --listen` +8. Install the required dependencies with `npm i` +0. Start the bot with `npm start` +10. You can interact with the bot by @mentioning it with your message +11. Install Stable Diffusion +12. Run the script `./webui.sh --api --listen` ### Set-up instructions with Docker 1. Install [Docker](https://docs.docker.com/get-docker/) From 1ca2daaa52a6980ea6ecc5c3ed963ec985c3610f Mon Sep 17 00:00:00 2001 From: hermitbernard <76450350+hermitbernard@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:01:39 +0200 Subject: [PATCH 5/8] Add attached text files processing --- src/bot.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/bot.js b/src/bot.js index 1bb3d84..8575812 100644 --- a/src/bot.js +++ b/src/bot.js @@ -401,6 +401,23 @@ client.on(Events.MessageCreate, async message => { if (userInput.length == 0) return; + // Process text files if attached + if (message.attachments.size > 0) { + const textAttachments = Array.from(message.attachments, ([, value]) => value).filter(att => att.contentType.startsWith("text")); + if (textAttachments.length > 0) { + try { + await Promise.all(textAttachments.map(async (att, i) => { + const response = await axios.get(att.url); + userInput += `\n${i + 1}. File - ${att.name}:\n${response.data}`; + })); + } catch (error) { + log(LogLevel.Error, `Failed to download text files: ${error}`); + await message.reply({ content: "Failed to download text files" }); + return; // Stop processing if file download fails + } + } + } + // create conversation if (messages[channelID] == null) { messages[channelID] = { amount: 0, last: null }; From b51d9936634aa894564707597376f46084174ab7 Mon Sep 17 00:00:00 2001 From: mekb Date: Mon, 30 Dec 2024 01:57:39 +1100 Subject: [PATCH 6/8] Remove disclaimer from README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index a41c5f1..388058b 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,6 @@

Discord chat with the bot

-### New Maintainer -This repository is no longer being developed on by me, [mekb-turtle](https://github.com/mekb-turtle). - ### Set-up instructions 1. Install [Node.js](https://nodejs.org) (if you have a package manager, use that instead to install this) - Make sure to install at least v14 of Node.js From 3e28ad6e59ba79ceec0818aca92e7cd5b00222ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20J=C4=99drzejewski?= Date: Sun, 9 Feb 2025 17:24:40 +0100 Subject: [PATCH 7/8] Added disclaimer --- .env.example | 2 +- README.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index dc2681a..056affb 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,7 @@ TOKEN= # What language model to use, orca is one of the lower-end models that doesn't require as much computer power as llama2 MODEL=orca -# Ollama URL (if you want to use multiple, separate them by commas) +# Ollama URL OLLAMA=http://localhost:11434 # Stable diffusion URL diff --git a/README.md b/README.md index 388058b..dd56f63 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@

Discord AI Bot

+

Repository is now in maintanance mode - rewriting project to Typescript

Discord bot to interact with Ollama and AUTOMATIC1111 Stable Diffusion as a chatbot

Stars

Discord chat with the bot

+The project started thanks to [mekb](https://github.com/mekb-turtle). + ### Set-up instructions 1. Install [Node.js](https://nodejs.org) (if you have a package manager, use that instead to install this) - Make sure to install at least v14 of Node.js From d33eeaa3499b3a64825f271467092a03ed81c8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20J=C4=99drzejewski?= Date: Wed, 12 Feb 2025 22:18:56 +0100 Subject: [PATCH 8/8] Added information about new branch --- README.md | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index dd56f63..1050bd5 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,46 @@
-

Discord AI Bot

-

Repository is now in maintanance mode - rewriting project to Typescript

-

Discord bot to interact with Ollama and AUTOMATIC1111 Stable Diffusion as a chatbot

-

Stars

-

Discord chat with the bot

+

Discord AI Bot

+

Repository is now in maintanance mode - rewriting project to Typescript on typescript branch

+

Discord bot to interact with Ollama and AUTOMATIC1111 Stable Diffusion as a chatbot

+

Stars

+

Discord chat with the bot

The project started thanks to [mekb](https://github.com/mekb-turtle). ### Set-up instructions + 1. Install [Node.js](https://nodejs.org) (if you have a package manager, use that instead to install this) - - Make sure to install at least v14 of Node.js + - Make sure to install at least v14 of Node.js 2. Install [Ollama](https://github.com/jmorganca/ollama) (ditto) 3. Pull (download) a model, e.g `ollama pull orca` or `ollama pull llama2` 4. Start Ollama by running `ollama serve` 5. [Create a Discord bot](https://discord.com/developers/applications) - - Under Application » Bot - - Enable Message Content Intent - - Enable Server Members Intent (for replacing user mentions with the username) + - Under Application » Bot + - Enable Message Content Intent + - Enable Server Members Intent (for replacing user mentions with the username) 6. Invite the bot to a server - 1. Go to Application » OAuth2 » URL Generator - 2. Enable `bot` - 3. Enable Send Messages, Read Messages/View Channels, and Read Message History - 4. Under Generated URL, click Copy and paste the URL in your browser + 1. Go to Application » OAuth2 » URL Generator + 2. Enable `bot` + 3. Enable Send Messages, Read Messages/View Channels, and Read Message History + 4. Under Generated URL, click Copy and paste the URL in your browser 7. Rename `.env.example` to `.env` and edit the `.env` file - - You can get the token from Application » Bot » Token, **never share this with anyone** - - Make sure to change the model if you aren't using `orca` - - Ollama URL can be kept the same unless you have changed the port - - You can use multiple Ollama servers at the same time by separating the URLs with commas - - Set the channels to the channel ID, comma separated - 1. In Discord, go to User Settings » Advanced, and enable Developer Mode - 2. Right click on a channel you want to use, and click Copy Channel ID - - You can edit the system message the bot uses, or disable it entirely + - You can get the token from Application » Bot » Token, **never share this with anyone** + - Make sure to change the model if you aren't using `orca` + - Ollama URL can be kept the same unless you have changed the port + - You can use multiple Ollama servers at the same time by separating the URLs with commas + - Set the channels to the channel ID, comma separated + 1. In Discord, go to User Settings » Advanced, and enable Developer Mode + 2. Right click on a channel you want to use, and click Copy Channel ID + - You can edit the system message the bot uses, or disable it entirely 8. Install the required dependencies with `npm i` -0. Start the bot with `npm start` +9. Start the bot with `npm start` 10. You can interact with the bot by @mentioning it with your message 11. Install Stable Diffusion 12. Run the script `./webui.sh --api --listen` ### Set-up instructions with Docker + 1. Install [Docker](https://docs.docker.com/get-docker/) - Should be atleast compatible with version 3 of compose (docker engine 1.13.0+) 2. Repeat steps 2—7 from the other setup instructions