diff --git a/.gitignore b/.gitignore index 39f745b39..ec1e67404 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ config.conf .DS_Store public/settings.json /thumbnails +whitelist.txt diff --git a/Dockerfile b/Dockerfile index 4bfabefd4..c19440a65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,10 @@ FROM node:19.1.0-alpine3.16 # Arguments ARG APP_HOME=/home/node/app +# Ensure proper handling of kernel signals +RUN apk add tini +ENTRYPOINT [ "tini", "--" ] + # Create app directory WORKDIR ${APP_HOME} @@ -42,4 +46,4 @@ RUN \ EXPOSE 8000 -ENTRYPOINT [ "/bin/sh", "-c", "./docker-entrypoint.sh" ] +CMD [ "./docker-entrypoint.sh" ] diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 7dae1e838..868062f80 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -300,7 +300,6 @@ " \"characters\",\n", " \"chats\",\n", " \"User Avatars\",\n", - " \"css\",\n", " \"worlds\",\n", " \"group chats\",\n", " \"groups\",\n", diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 1e7cf1245..74980632a 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -25,4 +25,4 @@ if [ ! -s "/home/node/app/config/settings.json" ]; then fi # Start the server -node /home/node/app/server.js +exec node /home/node/app/server.js diff --git a/public/index.html b/public/index.html index 3e241dde0..75271911b 100644 --- a/public/index.html +++ b/public/index.html @@ -1313,6 +1313,7 @@
+
- \ No newline at end of file + diff --git a/public/script.js b/public/script.js index da466049f..3a6cb7a15 100644 --- a/public/script.js +++ b/public/script.js @@ -878,7 +878,7 @@ function messageFormating(mes, ch_name, isSystem, forceAvatar) { mes = mes.replace(/\n/g, "
"); mes = mes.trim(); - mes = mes.replace(/[\s\S]*?<\/code>/g, function (match) { + mes = mes.replace(/[\s\S]*?<\/code>/g, function (match) { return match.replace(/&/g, '&'); }); } @@ -1344,7 +1344,7 @@ async function Generate(type, automatic_trigger, force_name2) { } else { //console.log('Regenerate call detected') var textareaText = ""; - if (chat[chat.length - 1]['is_user']) {//If last message from You + if (chat.length && chat[chat.length - 1]['is_user']) {//If last message from You } else if (type !== "swipe" && !isImpersonate) { @@ -1485,7 +1485,7 @@ async function Generate(type, automatic_trigger, force_name2) { if (!storyString.endsWith('\n')) { storyString += '\n'; } - const replaceString = power_user.disable_examples_formatting ? `This is how ${name2} should talk` : ''; + const replaceString = power_user.disable_examples_formatting ? '' : `This is how ${name2} should talk`; example = example.replace(//i, replaceString); } storyString += appendToStoryString(example, ''); @@ -3499,6 +3499,10 @@ $(document).ready(function () { chat[chat.length - 1]['swipes'][0] = chat[chat.length - 1]['mes']; //assign swipe array with last message from chat } chat[chat.length - 1]['swipe_id']++; //make new slot in array + // if message has memory attached - remove it to allow regen + if (chat[chat.length -1].extra && chat[chat.length -1].extra.memory) { + delete chat[chat.length -1].extra.memory; + } //console.log(chat[chat.length-1]['swipes']); if (parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) { //if swipe id of last message is the same as the length of the 'swipes' array @@ -5071,4 +5075,16 @@ $(document).ready(function () { closeMessageEditor(); } }); + + $("#bg-filter").on("input", function() { + const filterValue = $(this).val().toLowerCase(); + $("#bg_menu_content > div").each(function() { + const $bgContent = $(this); + if ($bgContent.attr("title").toLowerCase().includes(filterValue)) { + $bgContent.show(); + } else { + $bgContent.hide(); + } + }); + }); }) diff --git a/public/style.css b/public/style.css index fa35e5791..09b3e9f67 100644 --- a/public/style.css +++ b/public/style.css @@ -50,13 +50,12 @@ /* base variable for blur strength slider calculations */ --blurStrength: 10; + color-scheme: only light; + /*styles for the color picker*/ --tool-cool-color-picker-btn-bg: transparent; --tool-cool-color-picker-btn-border-color: transparent; - - color-scheme: only light; - } * { @@ -3631,4 +3630,4 @@ body.movingUI #expression-holder { overflow-y: auto; overflow-x: hidden; } -} \ No newline at end of file +} diff --git a/readme.md b/readme.md index 8f09e0c0e..80c6c29fc 100644 --- a/readme.md +++ b/readme.md @@ -134,6 +134,17 @@ Restart your TAI server. You will now be able to connect from other devices. +### Managing whitelisted IPs + +You can add or remove whitelisted IPs by editing the `whitelist` array in `config.conf`. You can also provide a `whitelist.txt` file in the same directory as `config.conf` with one IP address per line like: + +```txt +192.168.0.1 +192.168.0.2 +``` + +The `whitelist` array in `config.conf` will be ignored if `whitelist.txt` exists. + ***Disclaimer: Anyone else who knows your IP address and TAI port number will be able to connect as well*** To connect over wifi you'll need your PC's local wifi IP address @@ -144,8 +155,24 @@ if you want other people on the internet to connect, check [here](https://whatis Try enabling the No Blur Effect (Fast UI) mode on the User settings panel. +## I like your project! How do I contribute? + +### DO's + +1. Send pull requests +2. Send feature suggestions and issue reports using established templates +3. Read the readme file and built-in documentation before asking anything + +### DONT's + +1. Offer monetary donations +2. Send bug reports without providing any context +3. Ask the questions that were already answered numerous times + ## Questions or suggestions? -Contact us on Discord: Cohee#1207 or RossAscends#1779 +Contact us on: +* Discord: Cohee#1207 or RossAscends#1779 +* Reddit: /u/RossAscends or /u/sillylossy ## Screenshots image @@ -162,3 +189,6 @@ Contact us on Discord: Cohee#1207 or RossAscends#1779 * poe-api client adapted from https://github.com/ading2210/poe-api (GPL v3) * GraphQL files for poe: https://github.com/muharamdani/poe (ISC License) * KoboldAI Presets from KAI Lite: https://lite.koboldai.net/ +* Noto Sans font by Google (OFL license) +* Icon theme by Font Awesome https://fontawesome.com (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) +* Linux startup script by AlpinDale diff --git a/server.js b/server.js index 68931c640..72c3c3f90 100644 --- a/server.js +++ b/server.js @@ -31,7 +31,17 @@ const webp = require('webp-converter'); const config = require(path.join(process.cwd(), './config.conf')); const server_port = process.env.SILLY_TAVERN_PORT || config.port; -const whitelist = config.whitelist; + +const whitelistPath = path.join(process.cwd(), "./whitelist.txt"); +let whitelist = config.whitelist; + +if (fs.existsSync(whitelistPath)) { + try { + let whitelistTxt = fs.readFileSync(whitelistPath, 'utf-8'); + whitelist = whitelistTxt.split("\n").filter(ip => ip).map(ip => ip.trim()); + } catch (e) { } +} + const whitelistMode = config.whitelistMode; const autorun = config.autorun; const enableExtensions = config.enableExtensions; @@ -1548,47 +1558,51 @@ app.post("/importchat", urlencodedParser, function (request, response) { } const jsonData = json5.parse(data); - var new_chat = []; if (jsonData.histories !== undefined) { //console.log('/importchat confirms JSON histories are defined'); - let i = 0; - new_chat[i] = {}; - new_chat[0]['user_name'] = 'You'; - new_chat[0]['character_name'] = ch_name; - new_chat[0]['create_date'] = humanizedISO8601DateTime() //Date.now(); - i++; - jsonData.histories.histories[0].msgs.forEach(function (item) { - new_chat[i] = {}; - if (item.src.is_human == true) { - new_chat[i]['name'] = 'You'; - } else { - new_chat[i]['name'] = ch_name; - } - new_chat[i]['is_user'] = item.src.is_human; - new_chat[i]['is_name'] = true; - new_chat[i]['send_date'] = humanizedISO8601DateTime() //Date.now(); - new_chat[i]['mes'] = item.text; - i++; - }); - const chatJsonlData = new_chat.map(JSON.stringify).join('\n'); - //console.log('/importchat saving a file: '+ch_name+' - '+humanizedISO8601DateTime()+' imported.jsonl'); - fs.writeFile(chatsPath + avatar_url + '/' + ch_name + ' - ' + humanizedISO8601DateTime() + ' imported.jsonl', chatJsonlData, 'utf8', function (err) { //added ch_name and replaced Date.now() with humanizedISO8601DateTime + const chat = { + from(history) { + return [ + { + user_name: 'You', + character_name: ch_name, + create_date: humanizedISO8601DateTime(), - if (err) { - response.send(err); - return console.log(err); - //response.send(err); - } else { - //response.redirect("/"); - response.send({ res: true }); + }, + ...history.msgs.map( + (message) => ({ + name: message.src.is_human ? 'You' : ch_name, + is_user: message.src.is_human, + is_name: true, + send_date: humanizedISO8601DateTime(), + mes: message.text, + }) + )]; } + } + + const newChats = []; + (jsonData.histories.histories ?? []).forEach((history) => { + newChats.push(chat.from(history)); }); + const errors = []; + newChats.forEach(chat => fs.writeFile( + chatsPath + avatar_url + '/' + ch_name + ' - ' + humanizedISO8601DateTime() + ' imported.jsonl', + chat.map(JSON.stringify).join('\n'), + 'utf8', + (err) => err ?? errors.push(err) + ) + ); + + if (0 < errors.length) { + response.send('Errors occurred while writing character files. Errors: ' + JSON.stringify(errors)); + } + + response.send({res: true}); } else { response.send({ error: true }); - return; } - }); } if (format === 'jsonl') { @@ -2490,4 +2504,4 @@ function ensurePublicDirectoriesExist() { fs.mkdirSync(dir, { recursive: true }); } } -} \ No newline at end of file +} diff --git a/start.sh b/start.sh old mode 100755 new mode 100644 index b6a254e8b..da2cf0ad4 --- a/start.sh +++ b/start.sh @@ -22,4 +22,3 @@ fi npm i node server.js -