From 454994a7bdf149089ad6c959cc12d8fbef6e84a4 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Wed, 17 May 2023 03:55:23 +0900 Subject: [PATCH 01/79] Update readme.md with SD/TTS info --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index 5b6a380fe..000bd927d 100644 --- a/readme.md +++ b/readme.md @@ -65,6 +65,8 @@ Get in touch with the developers directly: * Character emotional expressions * Auto-Summary of the chat history * Sending images to chat, and the AI interpreting the content. + * Stable Diffusion image generation (5 chat-related presets plus 'free mode') + * Text-to-speech for AI response messages (via ElevenLabs, Silero, or the OS's System TTS) ## UI Extensions 🚀 @@ -76,6 +78,8 @@ Get in touch with the developers directly: | D&D Dice | A set of 7 classic D&D dice for all your dice rolling needs.

*I used to roll the dice.
Feel the fear in my enemies' eyes* | None | image | | Author's Note | Built-in extension that allows you to append notes that will be added to the context and steer the story and character in a specific direction. Because it's sent after the character description, it has a lot of weight. Thanks Aliážµ#2222 for pitching the idea! | None | ![image](https://user-images.githubusercontent.com/128647114/230311637-d809cd9b-af66-4dd1-a310-7a27e847c011.png) | | Character Backgrounds | Built-in extension to assign unique backgrounds to specific chats or groups. | None | image | +| Stable Diffusion | Use local of cloud-based Stable Diffusion webUI API to generate images. 5 presets included ('you', 'your face', 'me', 'the story', and 'the last message'. Free mode also supported via `/sd (anything_here_)` command in the chat input bar. Most common StableDiffusion generation settings are customizable within the SillyTavern UI. | None | image | +| Text-to-Speech | AI-generated voice will read back character messages on demand, or automatically read new messages they arrive. Supports ElevenLabs, Silero, and your device's TTS service. | None | image | ## UI/CSS/Quality of Life tweaks by RossAscends From fde5f7af84f15f5fef95bf898305365850d13eae Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Wed, 17 May 2023 04:00:05 +0900 Subject: [PATCH 02/79] Update readme.md with SD/TSS images --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 000bd927d..1687c59f2 100644 --- a/readme.md +++ b/readme.md @@ -78,8 +78,8 @@ Get in touch with the developers directly: | D&D Dice | A set of 7 classic D&D dice for all your dice rolling needs.

*I used to roll the dice.
Feel the fear in my enemies' eyes* | None | image | | Author's Note | Built-in extension that allows you to append notes that will be added to the context and steer the story and character in a specific direction. Because it's sent after the character description, it has a lot of weight. Thanks Aliážµ#2222 for pitching the idea! | None | ![image](https://user-images.githubusercontent.com/128647114/230311637-d809cd9b-af66-4dd1-a310-7a27e847c011.png) | | Character Backgrounds | Built-in extension to assign unique backgrounds to specific chats or groups. | None | image | -| Stable Diffusion | Use local of cloud-based Stable Diffusion webUI API to generate images. 5 presets included ('you', 'your face', 'me', 'the story', and 'the last message'. Free mode also supported via `/sd (anything_here_)` command in the chat input bar. Most common StableDiffusion generation settings are customizable within the SillyTavern UI. | None | image | -| Text-to-Speech | AI-generated voice will read back character messages on demand, or automatically read new messages they arrive. Supports ElevenLabs, Silero, and your device's TTS service. | None | image | +| Stable Diffusion | Use local of cloud-based Stable Diffusion webUI API to generate images. 5 presets included ('you', 'your face', 'me', 'the story', and 'the last message'. Free mode also supported via `/sd (anything_here_)` command in the chat input bar. Most common StableDiffusion generation settings are customizable within the SillyTavern UI. | None | image | +| Text-to-Speech | AI-generated voice will read back character messages on demand, or automatically read new messages they arrive. Supports ElevenLabs, Silero, and your device's TTS service. | None | image | ## UI/CSS/Quality of Life tweaks by RossAscends From a656783b156c9799d34af61f1bdfcfc9b6a60231 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 17 May 2023 01:13:35 +0300 Subject: [PATCH 03/79] Upgrade tensorflow in colab --- colab/GPU.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index caf939c44..194ba8dea 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -98,7 +98,7 @@ "!git clone https://github.com/Cohee1207/tts_samples\n", "!npm install -g localtunnel\n", "!pip install -r requirements-complete.txt\n", - "!pip install tensorflow==2.11\n", + "!pip install tensorflow==2.12\n", "\n", "\n", "cmd = f\"python server.py {' '.join(params)}\"\n", From cf4492b7e4ded49078da14d51e0e77d23b725484 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 17 May 2023 20:50:25 +0300 Subject: [PATCH 04/79] Busy icon for inline SD gens --- .../extensions/stable-diffusion/index.js | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 86356ec0c..0cfd3fea9 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -609,23 +609,44 @@ addSDGenButtons(); setInterval(moduleWorker, UPDATE_INTERVAL); -function sdMessageButton(e) { +async function sdMessageButton(e) { + function setBusyIcon(isBusy) { + $icon.toggleClass('fa-paintbrush', !isBusy); + $icon.toggleClass(busyClass, isBusy); + } + + const busyClass = 'fa-hourglass'; const context = getContext(); - const $mes = $(e.currentTarget).closest('.mes'); + const $icon = $(e.currentTarget); + const $mes = $icon.closest('.mes'); const characterName = $mes.find('.name_text').text(); const messageText = $mes.find('.mes_text').text(); const message_id = $mes.attr('mesid'); const message = context.chat[message_id]; const hasSavedImage = message?.extra?.image && message?.extra?.title; - if (hasSavedImage) { - const prompt = message?.extra?.title; - console.log('Regenerating an image, using existing prompt:', prompt); - sendGenerationRequest(prompt, saveGeneratedImage); + if ($icon.hasClass(busyClass)) { + console.log('Previous image is still being generated...'); + return; } - else { - console.log("doing /sd raw last"); - generatePicture('sd', 'raw_last', `${characterName} said: ${messageText}`, saveGeneratedImage); + + try { + setBusyIcon(true); + if (hasSavedImage) { + const prompt = message?.extra?.title; + console.log('Regenerating an image, using existing prompt:', prompt); + await sendGenerationRequest(prompt, saveGeneratedImage); + } + else { + console.log("doing /sd raw last"); + await generatePicture('sd', 'raw_last', `${characterName} said: ${messageText}`, saveGeneratedImage); + } + } + catch (error) { + console.error('Could not generate inline image: ', error); + } + finally { + setBusyIcon(false); } function saveGeneratedImage(prompt, image) { @@ -689,7 +710,7 @@ jQuery(async () => {
- Use slash commands or the bottom Paintbrush buttron to generate images. Type /help in chat for more details + Use slash commands or the bottom Paintbrush button to generate images. Type /help in chat for more details
Hint: Save an API key in Horde KoboldAI API settings to use it here.
From f3088517b9d267b2cb607616461938776cc60e92 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 17 May 2023 20:50:47 +0300 Subject: [PATCH 05/79] Save chat after sending system message --- public/scripts/slash-commands.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index b3168c92d..48704b01e 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -113,6 +113,7 @@ function sendNarratorMessage(_, text) { chat.push(message); addOneMessage(message); + saveChatConditional(); } function helpCommandCallback() { From 60bf3f4a70c58b7d2a8def94e07455c6f1130736 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 17 May 2023 20:53:32 +0300 Subject: [PATCH 06/79] Add toast notifications plugin --- public/css/toastr.min.css | 1 + public/index.html | 2 ++ public/scripts/toastr.min.js | 7 +++++++ 3 files changed, 10 insertions(+) create mode 100644 public/css/toastr.min.css create mode 100644 public/scripts/toastr.min.js diff --git a/public/css/toastr.min.css b/public/css/toastr.min.css new file mode 100644 index 000000000..643135ea0 --- /dev/null +++ b/public/css/toastr.min.css @@ -0,0 +1 @@ +/* * Note that this is toastr v2.1.3, the "latest" version in url has no more maintenance, * please go to https://cdnjs.com/libraries/toastr.js and pick a certain version you want to use, * make sure you copy the url from the website since the url may change between versions. * */ .toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#FFF}.toast-message a:hover{color:#CCC;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#FFF;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);line-height:1}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}.rtl .toast-close-button{left:-.3em;float:left;right:.3em}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999;pointer-events:none}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 4d231c692..bc910b326 100644 --- a/public/index.html +++ b/public/index.html @@ -14,6 +14,7 @@ + @@ -41,6 +42,7 @@ + diff --git a/public/scripts/toastr.min.js b/public/scripts/toastr.min.js new file mode 100644 index 000000000..4b5f34a05 --- /dev/null +++ b/public/scripts/toastr.min.js @@ -0,0 +1,7 @@ +/* + * Note that this is toastr v2.1.3, the "latest" version in url has no more maintenance, + * please go to https://cdnjs.com/libraries/toastr.js and pick a certain version you want to use, + * make sure you copy the url from the website since the url may change between versions. + * */ +!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("
").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e("
"),M=e("
"),B=e("
"),q=e("
"),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.3",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)}); +//# sourceMappingURL=toastr.js.map From ba4d7fa3eacb4ee61d3c17a35cac136a2e7c960d Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Thu, 18 May 2023 02:58:27 +0900 Subject: [PATCH 07/79] =?UTF-8?q?=E2=98=A0=20better=20character=20deletion?= =?UTF-8?q?=20warning=20=E2=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 4 ++-- public/script.js | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 4d231c692..bcaa6e702 100644 --- a/public/index.html +++ b/public/index.html @@ -1156,7 +1156,7 @@
- +
For privacy reasons, your API key will be hidden after you reload the page.
@@ -1909,7 +1909,7 @@ - +
 
diff --git a/public/script.js b/public/script.js index 439c9799e..cbe20fd6d 100644 --- a/public/script.js +++ b/public/script.js @@ -5412,8 +5412,11 @@ $(document).ready(function () { $("#delete_button").click(function () { popup_type = "del_ch"; - callPopup( - "

Delete the character?

Your chat will be closed." + callPopup(` +

Delete the character?

+ THIS IS PERMANENT!

+ THIS WILL ALSO DELETE ALL
+ OF THE CHARACTER'S CHAT FILES.

` ); }); From 3f8435f6766dfad8ef294b5a8e94ed151905cdc0 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 17 May 2023 21:02:09 +0300 Subject: [PATCH 08/79] Display toast when narrator name is set --- package-lock.json | 12 +++++++++++- package.json | 3 ++- public/index.html | 9 +++++++++ public/scripts/slash-commands.js | 4 +++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea8a4457f..fb027e06a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,8 @@ }, "devDependencies": { "pkg": "^5.8.1", - "pkg-fetch": "^3.5.2" + "pkg-fetch": "^3.5.2", + "toastr": "^2.1.4" } }, "node_modules/@babel/generator": { @@ -3031,6 +3032,15 @@ "node": ">=8.0" } }, + "node_modules/toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==", + "dev": true, + "dependencies": { + "jquery": ">=1.12.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "license": "MIT", diff --git a/package.json b/package.json index 48bbccd0f..49548b351 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ }, "devDependencies": { "pkg": "^5.8.1", - "pkg-fetch": "^3.5.2" + "pkg-fetch": "^3.5.2", + "toastr": "^2.1.4" } } diff --git a/public/index.html b/public/index.html index bc910b326..c051c3df8 100644 --- a/public/index.html +++ b/public/index.html @@ -2577,6 +2577,15 @@
+ + \ No newline at end of file diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 48704b01e..74921c77b 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -88,7 +88,9 @@ const NARRATOR_NAME_KEY = 'narrator_name'; const NARRATOR_NAME_DEFAULT = 'System'; function setNarratorName(_, text) { - chat_metadata[NARRATOR_NAME_KEY] = text || NARRATOR_NAME_DEFAULT; + const name = text || NARRATOR_NAME_DEFAULT; + chat_metadata[NARRATOR_NAME_KEY] = name; + toastr.info(`System narrator name set to ${name}`); saveChatConditional(); } From 5a95fed1345cfe74abb098709d76b2c61337f497 Mon Sep 17 00:00:00 2001 From: Maya <48323879+mayaeary@users.noreply.github.com> Date: Wed, 17 May 2023 19:17:44 +0000 Subject: [PATCH 09/79] Add Karras and hiding of SD buttons --- public/scripts/extensions.js | 1 - .../extensions/stable-diffusion/index.js | 31 ++++++++++++++----- public/style.css | 2 -- server.js | 1 + 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index e5dfd8f15..0e4e8882c 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -193,7 +193,6 @@ async function connectToApi(baseUrl) { modules = data.modules; await activateExtensions(); eventSource.emit(event_types.EXTRAS_CONNECTED, modules); - $("#extensionsMenuButton").css("display", "flex"); } updateStatus(getExtensionsResult.ok); diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 0cfd3fea9..304666b53 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -106,6 +106,7 @@ const defaultSettings = { // Horde settings horde: false, horde_nsfw: false, + horde_karras: true, } async function loadSettings() { @@ -121,6 +122,7 @@ async function loadSettings() { $('#sd_height').val(extension_settings.sd.height).trigger('input'); $('#sd_horde').prop('checked', extension_settings.sd.horde); $('#sd_horde_nsfw').prop('checked', extension_settings.sd.horde_nsfw); + $('#sd_horde_karras').prop('checked', extension_settings.sd.horde_karras); $('#sd_restore_faces').prop('checked', extension_settings.sd.restore_faces); $('#sd_enable_hr').prop('checked', extension_settings.sd.enable_hr); @@ -181,6 +183,11 @@ async function onHordeNsfwInput() { saveSettingsDebounced(); } +async function onHordeKarrasInput() { + extension_settings.sd.horde_karras = !!$(this).prop('checked'); + saveSettingsDebounced(); +} + function onRestoreFacesInput() { extension_settings.sd.restore_faces = !!$(this).prop('checked'); saveSettingsDebounced(); @@ -473,6 +480,7 @@ async function generateExtrasImage(prompt, callback) { negative_prompt: extension_settings.sd.negative_prompt, restore_faces: !!extension_settings.sd.restore_faces, enable_hr: !!extension_settings.sd.enable_hr, + karras: !!extension_settings.sd.horde_karras, }), }); @@ -592,17 +600,19 @@ function addSDGenButtons() { }); } -async function moduleWorker() { - const context = getContext(); +function isConnectedToExtras() { + return modules.includes('sd'); +} - if (context.onlineStatus === 'no_connection') { - $('#sd_gen').hide(200); - $('.sd_message_gen').hide(); - } - else { +async function moduleWorker() { + if (isConnectedToExtras() || extension_settings.sd.horde) { $('#sd_gen').show(200); $('.sd_message_gen').show(); } + else { + $('#sd_gen').hide(200); + $('.sd_message_gen').hide(); + } } addSDGenButtons(); @@ -746,6 +756,12 @@ jQuery(async () => { +
+ +
@@ -764,6 +780,7 @@ jQuery(async () => { $('#sd_height').on('input', onHeightInput); $('#sd_horde').on('input', onHordeInput); $('#sd_horde_nsfw').on('input', onHordeNsfwInput); + $('#sd_horde_karras').on('input', onHordeKarrasInput); $('#sd_restore_faces').on('input', onRestoreFacesInput); $('#sd_enable_hr').on('input', onHighResFixInput); diff --git a/public/style.css b/public/style.css index 139a7b626..3b2e7c375 100644 --- a/public/style.css +++ b/public/style.css @@ -500,8 +500,6 @@ code { display: flex; align-items: center; justify-content: center; - display: none; - } #extensionsMenuButton:hover { diff --git a/server.js b/server.js index 189b42076..03e80abcd 100644 --- a/server.js +++ b/server.js @@ -2981,6 +2981,7 @@ app.post('/horde_generateimage', jsonParser, async (request, response) => { steps: request.body.steps, width: request.body.width, height: request.body.height, + karras: Boolean(request.body.karras), n: 1, }, r2: false, From 0c857ab604976b1210b9382afd7065068707f844 Mon Sep 17 00:00:00 2001 From: Maya <48323879+mayaeary@users.noreply.github.com> Date: Wed, 17 May 2023 19:20:45 +0000 Subject: [PATCH 10/79] Sort models for SD horde --- public/scripts/extensions/stable-diffusion/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 304666b53..c69e993dc 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -296,8 +296,10 @@ async function loadHordeModels() { headers: getRequestHeaders(), }); + if (result.ok) { const data = await result.json(); + data.sort((a, b) => b.count - a.count); const models = data.map(x => ({ value: x.name, text: `${x.name} (ETA: ${x.eta}s, Queue: ${x.queued}, Workers: ${x.count})` })); return models; } From 661b4fec9a43a8b08c14ec407f5576c35d88a3e8 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Thu, 18 May 2023 04:23:19 +0900 Subject: [PATCH 11/79] allow dice even without Extras connection --- public/scripts/extensions.js | 8 ++++++-- public/scripts/extensions/stable-diffusion/index.js | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index e5dfd8f15..033906e5a 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -193,7 +193,7 @@ async function connectToApi(baseUrl) { modules = data.modules; await activateExtensions(); eventSource.emit(event_types.EXTRAS_CONNECTED, modules); - $("#extensionsMenuButton").css("display", "flex"); + } updateStatus(getExtensionsResult.ok); @@ -318,7 +318,11 @@ async function loadExtensionSettings(settings) { } $(document).ready(async function () { - setTimeout(function () { addExtensionsButtonAndMenu(); }, 100) + setTimeout(function () { + addExtensionsButtonAndMenu(); + $("#extensionsMenuButton").css("display", "flex"); + }, 100) + $("#extensions_connect").on('click', connectClickHandler); $("#extensions_autoconnect").on('input', autoConnectInputHandler); $("#extensions_details").on('click', showExtensionsDetails); diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 0cfd3fea9..1b552a47a 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -303,6 +303,8 @@ async function loadExtrasModels() { return []; } + addSDGenButtons(); + const url = new URL(getApiUrl()); url.pathname = '/api/image/model'; const getCurrentModelResult = await fetch(url, defaultRequestArgs); @@ -605,7 +607,7 @@ async function moduleWorker() { } } -addSDGenButtons(); + setInterval(moduleWorker, UPDATE_INTERVAL); From ef30befd4dea06180bef817ffa10292ae7827c7e Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Thu, 18 May 2023 04:41:01 +0900 Subject: [PATCH 12/79] revert SD icon to show even without Extras present --- public/scripts/extensions/stable-diffusion/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 1b552a47a..0cfd3fea9 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -303,8 +303,6 @@ async function loadExtrasModels() { return []; } - addSDGenButtons(); - const url = new URL(getApiUrl()); url.pathname = '/api/image/model'; const getCurrentModelResult = await fetch(url, defaultRequestArgs); @@ -607,7 +605,7 @@ async function moduleWorker() { } } - +addSDGenButtons(); setInterval(moduleWorker, UPDATE_INTERVAL); From 069316218adf0d44fb71e1905a3bef2417d3cec3 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 18 May 2023 00:17:20 +0300 Subject: [PATCH 13/79] Adjust caption extension to new menu --- public/scripts/extensions/caption/index.js | 28 ++++++++++--------- public/scripts/extensions/caption/style.css | 21 -------------- .../extensions/stable-diffusion/index.js | 4 +-- public/style.css | 5 ++++ 4 files changed, 22 insertions(+), 36 deletions(-) diff --git a/public/scripts/extensions/caption/index.js b/public/scripts/extensions/caption/index.js index 992413213..535be7620 100644 --- a/public/scripts/extensions/caption/index.js +++ b/public/scripts/extensions/caption/index.js @@ -15,9 +15,9 @@ async function moduleWorker() { async function setImageIcon() { try { - const sendButton = document.getElementById('send_picture'); - sendButton.classList.add('fa-image'); - sendButton.classList.remove('fa-hourglass-half'); + const sendButton = $('#send_picture .extensionsMenuExtensionButton'); + sendButton.addClass('fa-image'); + sendButton.removeClass('fa-hourglass-half'); } catch (error) { console.log(error); @@ -26,9 +26,9 @@ async function setImageIcon() { async function setSpinnerIcon() { try { - const sendButton = document.getElementById('send_picture'); - sendButton.classList.remove('fa-image'); - sendButton.classList.add('fa-hourglass-half'); + const sendButton = $('#send_picture .extensionsMenuExtensionButton'); + sendButton.removeClass('fa-image'); + sendButton.addClass('fa-hourglass-half'); } catch (error) { console.log(error); @@ -92,15 +92,17 @@ async function onSelectImage(e) { } } -$(document).ready(function () { +jQuery(function () { function addSendPictureButton() { - const sendButton = document.createElement('div'); - sendButton.id = 'send_picture'; - sendButton.title = 'Send a picture to chat'; - sendButton.classList.add('fa-solid'); + const sendButton = $(` +
+
+ Send a picture +
`); + + $('#extensionsMenu').prepend(sendButton); $(sendButton).hide(); - $(sendButton).on('click', () => $('#img_file').click()); - $('#send_but_sheld').prepend(sendButton); + $(sendButton).on('click', () => $('#img_file').trigger('click')); } function addPictureSendForm() { const inputHtml = ``; diff --git a/public/scripts/extensions/caption/style.css b/public/scripts/extensions/caption/style.css index 044c21800..58f93eb55 100644 --- a/public/scripts/extensions/caption/style.css +++ b/public/scripts/extensions/caption/style.css @@ -1,24 +1,3 @@ -#send_picture { - order: 200; - width: 40px; - height: 40px; - margin: 0; - padding: 1px; - outline: none; - border: none; - cursor: pointer; - transition: 0.3s; - opacity: 0.7; - display: flex; - align-items: center; - justify-content: center; -} - -#send_picture:hover { - opacity: 1; - filter: brightness(1.2); -} - #img_form { display: none; } diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 1222bd22c..c4b5b9d61 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -549,7 +549,7 @@ function addSDGenButtons() { const buttonHtml = `
- StableDiffusion + Stable Diffusion
`; @@ -757,7 +757,7 @@ jQuery(async () => { -
+
-
@@ -2203,6 +2201,58 @@
+
+
+

Context Template Editor

+ +
+
+ Substitution Parameters +
+
+
+ Click to copy. +
    +
  • {{char}} - current character name
  • +
  • {{user}} - current user name
  • +
  • {{description}} - character description
  • +
  • {{scenario}} - character or group scenario
  • +
  • {{personality}} - character personality
  • +
  • {{mesExamples}} - message examples
  • +
  • {{wiBeforeCharacter}} - activated World Info entries (Before Char)
  • +
  • {{wiAfterCharacter}} - activated World Info entries (After Char)
  • +
  • {{instructSystemPrompt}} - system prompt (Instruct mode only)
  • +
+
+
+
+
+ Story String Template +
+ +
+ Lines containing parameters resolving to an empty value will be removed from the template string. +
+
+
+
+ Chat Injections + +
+
+
+
+
+ +
+
+ + + +
+
diff --git a/public/scripts/context-template.js b/public/scripts/context-template.js new file mode 100644 index 000000000..d7480b1dc --- /dev/null +++ b/public/scripts/context-template.js @@ -0,0 +1,28 @@ +import { + callPopup, +} from '../script.js'; + +function openContextTemplateEditor() { + const editor = $('#context_editor_template .context_editor').clone(); + $('#dialogue_popup').addClass('large_dialogue_popup wide_dialogue_popup'); + callPopup(editor.html(), 'text'); +} + +function copyTemplateParameter(event) { + const text = $(event.target).text(); + navigator.clipboard.writeText(text); + const copiedMsg = document.createElement("div"); + copiedMsg.classList.add('code-copied'); + copiedMsg.innerText = "Copied!"; + copiedMsg.style.top = `${event.clientY - 55}px`; + copiedMsg.style.left = `${event.clientX - 55}px`; + document.body.append(copiedMsg); + setTimeout(() => { + document.body.removeChild(copiedMsg); + }, 1000); +} + +jQuery(() => { + $('#context_template_edit').on('click', openContextTemplateEditor); + $(document).on('pointerup', '.template_parameters_list code', copyTemplateParameter); +}) \ No newline at end of file diff --git a/public/style.css b/public/style.css index d5bc238d0..9a69c05c5 100644 --- a/public/style.css +++ b/public/style.css @@ -921,6 +921,26 @@ select { } +.chat_injections_list:empty { + width: 100%; + height: 100%; +} + +.chat_injections_list:empty::before { + display: flex; + align-items: center; + justify-content: center; + content: "No injections"; + font-weight: bolder; + width: 100%; + height: 100%; + opacity: 0.8; + min-height: 3rem; +} + +.template_parameters_list code { + cursor: pointer; +} h3 { margin: 10px 0; @@ -3602,7 +3622,7 @@ label[for="extensions_autoconnect"] { .code-copied { position: absolute; - z-index: 99; + z-index: 10000; font-size: var(--mainFontSize); color: var(--SmartThemeBodyColor); background-color: var(--SmartThemeFastUIBGColor); @@ -3744,6 +3764,10 @@ toolcool-color-picker { flex: 1; } +.flex2 { + flex: 2; +} + .flexFlowColumn { flex-flow: column; } From d74a920e19e86432cb637dbddcc437cd74645e19 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 19 May 2023 21:42:01 +0300 Subject: [PATCH 51/79] Auto-swipe blacklist to textarea --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index b60005cc7..6b013b369 100644 --- a/public/index.html +++ b/public/index.html @@ -1772,7 +1772,7 @@
Blacklisted words
- +
Blacklisted word count to swipe
From df0734aac40cc7dbb358de9614e93879572b1530 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 19 May 2023 23:05:22 +0300 Subject: [PATCH 52/79] #336 Slash commands / bias adjustments --- public/script.js | 86 +++++++++++++++++++++----------- public/scripts/openai.js | 4 +- public/scripts/slash-commands.js | 17 ++++++- 3 files changed, 75 insertions(+), 32 deletions(-) diff --git a/public/script.js b/public/script.js index c8f3c08bd..a4519fda0 100644 --- a/public/script.js +++ b/public/script.js @@ -294,7 +294,7 @@ const system_messages = { mes: [ `Hi there! The following chat formatting commands are supported:
    -
  • {{text}} - sets a one-time behavioral bias for the AI. Resets when you send the next message. +
  • {​{text}​} - sets a one-time behavioral bias for the AI. Resets when you send the next message.
Hotkeys/Keybinds: @@ -1027,6 +1027,11 @@ function messageFormatting(mes, ch_name, isSystem, isUser) { }); } + // Hides bias from empty messages send with slash commands + if (isSystem) { + mes = mes.replace(/{{(\*?.*\*?)}}/g, ""); + } + if (!power_user.allow_name2_display && ch_name && !isUser && !isSystem) { mes = mes.replaceAll(`${ch_name}:`, ""); } @@ -1160,7 +1165,7 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true newMessage.data("isSystem", isSystem); if (isSystem) { - newMessage.find(".mes_edit").hide(); + // newMessage.find(".mes_edit").hide(); newMessage.find(".mes_prompt").hide(); //don't need prompt button for sys } @@ -1320,7 +1325,7 @@ function processCommands(message, type) { return result.interrupt; } -function sendSystemMessage(type, text) { +function sendSystemMessage(type, text, extra = {}) { const systemMessage = system_messages[type]; if (!systemMessage) { @@ -1341,6 +1346,7 @@ function sendSystemMessage(type, text) { newMessage.extra = {}; } + newMessage.extra = Object.assign(newMessage.extra, extra); newMessage.extra.type = type; chat.push(newMessage); @@ -1348,7 +1354,7 @@ function sendSystemMessage(type, text) { is_send_press = false; } -function extractMessageBias(message) { +export function extractMessageBias(message) { if (!message) { return null; } @@ -1744,7 +1750,13 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, //for normal messages sent from user.. if (textareaText != "" && !automatic_trigger && type !== 'quiet') { - sendMessageAsUser(textareaText, messageBias); + // If user message contains no text other than bias - send as a system message + if (messageBias && replaceBiasMarkup(textareaText).trim().length === 0) { + sendSystemMessage(system_message_types.GENERIC, ' ', { bias: messageBias }); + } + else { + sendMessageAsUser(textareaText, messageBias); + } } //////////////////////////////////// const scenarioText = chat_metadata['scenario'] || characters[this_chid].scenario; @@ -2360,8 +2372,8 @@ function getBiasStrings(textareaText) { // gets bias of the latest message where it was applied for (let mes of chat.slice().reverse()) { - if (mes && mes.is_user) { - if (mes.extra && mes.extra.bias && mes.extra.bias.trim().length > 0) { + if (mes && mes.extra && (mes.is_user || mes.is_system || mes.extra.type === system_message_types.NARRATOR)) { + if (mes.extra.bias && mes.extra.bias.trim().length > 0) { promptBias = mes.extra.bias; } break; @@ -2384,12 +2396,15 @@ function formatMessageHistoryItem(chatItem, isInstruct) { textResult = formatInstructModeChat(itemName, chatItem.mes, chatItem.is_user, isNarratorType, chatItem.force_avatar); } - // replace bias markup - textResult = (textResult ?? '').replace(/{{(\*?.*\*?)}}/g, ''); + textResult = replaceBiasMarkup(textResult); return textResult; } +export function replaceBiasMarkup(str) { + return (str ?? '').replace(/{{(\*?.*\*?)}}/g, ''); +} + function sendMessageAsUser(textareaText, messageBias) { chat[chat.length] = {}; chat[chat.length - 1]['name'] = name1; @@ -3882,22 +3897,30 @@ function messageEditAuto(div) { let mesBlock = div.closest(".mes_block"); var text = mesBlock.find(".edit_textarea").val().trim(); const bias = extractMessageBias(text); - chat[this_edit_mes_id]["mes"] = text; - if (chat[this_edit_mes_id]["swipe_id"] !== undefined) { - chat[this_edit_mes_id]["swipes"][chat[this_edit_mes_id]["swipe_id"]] = text; + const mes = chat[this_edit_mes_id]; + mes["mes"] = text; + if (mes["swipe_id"] !== undefined) { + mes["swipes"][mes["swipe_id"]] = text; } // editing old messages - if (!chat[this_edit_mes_id]["extra"]) { - chat[this_edit_mes_id]["extra"] = {}; + if (!mes["extra"]) { + mes["extra"] = {}; } - chat[this_edit_mes_id]["extra"]["bias"] = bias ?? null; + + if (mes.is_system || mes.is_user || mes.extra.type === system_message_types.NARRATOR) { + mes.extra.bias = bias ?? null; + } + else { + mes.extra.bias = null; + } + mesBlock.find(".mes_text").val(''); mesBlock.find(".mes_text").val(messageFormatting( text, this_edit_mes_chname, - chat[this_edit_mes_id].is_system, - chat[this_edit_mes_id].is_user, + mes.is_system, + mes.is_user, )); saveChatDebounced(); } @@ -3906,17 +3929,23 @@ function messageEditDone(div) { let mesBlock = div.closest(".mes_block"); var text = mesBlock.find(".edit_textarea").val().trim(); const bias = extractMessageBias(text); - chat[this_edit_mes_id]["mes"] = text; - if (chat[this_edit_mes_id]["swipe_id"] !== undefined) { - chat[this_edit_mes_id]["swipes"][chat[this_edit_mes_id]["swipe_id"]] = text; + const mes = chat[this_edit_mes_id]; + mes["mes"] = text; + if (mes["swipe_id"] !== undefined) { + mes["swipes"][mes["swipe_id"]] = text; } // editing old messages - if (!chat[this_edit_mes_id]["extra"]) { - chat[this_edit_mes_id]["extra"] = {}; + if (!mes.extra) { + mes.extra = {}; } - chat[this_edit_mes_id]["extra"]["bias"] = bias ?? null; + if (mes.is_system || mes.is_user || mes.extra.type === system_message_types.NARRATOR) { + mes.extra.bias = bias ?? null; + } + else { + mes.extra.bias = null; + } mesBlock.find(".mes_text").empty(); mesBlock.find(".mes_edit_buttons").css("display", "none"); @@ -3925,13 +3954,13 @@ function messageEditDone(div) { messageFormatting( text, this_edit_mes_chname, - chat[this_edit_mes_id].is_system, - chat[this_edit_mes_id].is_user, + mes.is_system, + mes.is_user, ) ); mesBlock.find(".mes_bias").empty(); mesBlock.find(".mes_bias").append(messageFormatting(bias)); - appendImageToMessage(chat[this_edit_mes_id], div.closest(".mes")); + appendImageToMessage(mes, div.closest(".mes")); addCopyToCodeBlocks(div.closest(".mes")); this_edit_mes_id = undefined; saveChatConditional(); @@ -5956,11 +5985,12 @@ $(document).ready(function () { //***Message Editor*** $(document).on("click", ".mes_edit", function () { if (this_chid !== undefined || selected_group) { - const message = $(this).closest(".mes"); + // Previously system messages we're allowed to be edited + /*const message = $(this).closest(".mes"); if (message.data("isSystem")) { return; - } + }*/ let chatScrollPosition = $("#chat").scrollTop(); if (this_edit_mes_id !== undefined) { diff --git a/public/scripts/openai.js b/public/scripts/openai.js index 2b80dd64a..bc35e3b05 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -18,6 +18,7 @@ import { callPopup, getRequestHeaders, system_message_types, + replaceBiasMarkup, } from "../script.js"; import { groups, selected_group } from "./group-chats.js"; @@ -174,8 +175,7 @@ function setOpenAIMessages(chat) { content = `${chat[j].name}: ${content}`; } - // replace bias markup - content = (content ?? '').replace(/{{(\*?.*\*?)}}/g, ''); + content = replaceBiasMarkup(content); // remove caret return (waste of tokens) content = content.replace(/\r/gm, ''); diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index b42195897..584bbb40c 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -4,7 +4,9 @@ import { chat, chat_metadata, default_avatar, + extractMessageBias, getThumbnailUrl, + replaceBiasMarkup, saveChatConditional, sendSystemMessage, system_avatar, @@ -117,6 +119,9 @@ function sendMessageAs(_, text) { const name = parts.shift().trim(); const mesText = parts.join('\n').trim(); + // Messages that do nothing but set bias will be hidden from the context + const bias = extractMessageBias(mesText); + const isSystem = replaceBiasMarkup(mesText).trim().length === 0; const character = characters.find(x => x.name === name); let force_avatar, original_avatar; @@ -134,11 +139,14 @@ function sendMessageAs(_, text) { name: name, is_user: false, is_name: true, - is_system: false, + is_system: isSystem, send_date: humanizedDateTime(), mes: mesText, force_avatar: force_avatar, original_avatar: original_avatar, + extra: { + bias: bias.trim().length ? bias : null, + } }; chat.push(message); @@ -152,16 +160,21 @@ function sendNarratorMessage(_, text) { } const name = chat_metadata[NARRATOR_NAME_KEY] || NARRATOR_NAME_DEFAULT; + // Messages that do nothing but set bias will be hidden from the context + const bias = extractMessageBias(text); + const isSystem = replaceBiasMarkup(text).trim().length === 0; + const message = { name: name, is_user: false, is_name: false, - is_system: false, + is_system: isSystem, send_date: humanizedDateTime(), mes: text.trim(), force_avatar: system_avatar, extra: { type: system_message_types.NARRATOR, + bias: bias.trim().length ? bias : null, }, }; From 2c2b45119bfb54d9be12f9003eae8b37500f918f Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 19 May 2023 23:12:39 +0300 Subject: [PATCH 53/79] Properly check for system TTS support --- public/script.js | 6 +++--- public/scripts/extensions/tts/system.js | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/public/script.js b/public/script.js index dab17418d..f809c2dcd 100644 --- a/public/script.js +++ b/public/script.js @@ -1615,10 +1615,10 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, // Set empty promise resolution functions if (typeof resolve !== 'function') { - resolve = () => {}; + resolve = () => { }; } if (typeof reject !== 'function') { - reject = () => {}; + reject = () => { }; } if (selected_group && !is_group_generating) { @@ -4080,7 +4080,7 @@ function isHordeGenerationNotAllowed() { } export function cancelTtsPlay() { - if (speechSynthesis) { + if ('speechSynthesis' in window) { speechSynthesis.cancel(); } } diff --git a/public/scripts/extensions/tts/system.js b/public/scripts/extensions/tts/system.js index e07a32843..57d322a63 100644 --- a/public/scripts/extensions/tts/system.js +++ b/public/scripts/extensions/tts/system.js @@ -29,7 +29,7 @@ class SystemTtsProvider { } get settingsHtml() { - if (!window.speechSynthesis) { + if (!('speechSynthesis' in window)) { return "Your browser or operating system doesn't support speech synthesis"; } @@ -80,7 +80,7 @@ class SystemTtsProvider { // TTS Interfaces // //#################// fetchTtsVoiceIds() { - if (!window.speechSynthesis) { + if (!('speechSynthesis' in window)) { return []; } @@ -91,6 +91,10 @@ class SystemTtsProvider { } previewTtsVoice(voiceId) { + if (!('speechSynthesis' in window)) { + throw 'Speech synthesis API is not supported'; + } + const voice = speechSynthesis.getVoices().find(x => x.voiceURI === voiceId); if (!voice) { @@ -107,11 +111,11 @@ class SystemTtsProvider { } async getVoice(voiceName) { - if (!window.speechSynthesis) { + if (!('speechSynthesis' in window)) { return { voice_id: null } } - const voices = window.speechSynthesis.getVoices(); + const voices = speechSynthesis.getVoices(); const match = voices.find(x => x.name == voiceName); if (!match) { @@ -122,7 +126,7 @@ class SystemTtsProvider { } async generateTts(text, voiceId) { - if (!window.speechSynthesis) { + if (!('speechSynthesis' in window)) { throw 'Speech synthesis API is not supported'; } From d50067270c1b6b1727fd58b12cbadf406747a0f6 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 19 May 2023 23:40:57 +0300 Subject: [PATCH 54/79] #321 Predict trailing asterisk during streaming --- public/script.js | 8 +++++++- public/scripts/utils.js | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 06d7c1045..dd77a6e8b 100644 --- a/public/script.js +++ b/public/script.js @@ -107,7 +107,7 @@ import { setPoeOnlineStatus, } from "./scripts/poe.js"; -import { debounce, delay, restoreCaretPosition, saveCaretPosition, end_trim_to_sentence } from "./scripts/utils.js"; +import { debounce, delay, restoreCaretPosition, saveCaretPosition, end_trim_to_sentence, countOccurrences, isOdd } from "./scripts/utils.js"; import { extension_settings, loadExtensionSettings } from "./scripts/extensions.js"; import { executeSlashCommands, getSlashCommandsHelp, registerSlashCommand } from "./scripts/slash-commands.js"; import { @@ -1516,6 +1516,12 @@ class StreamingProcessor { let isName = result.this_mes_is_name; processedText = result.getMessage; + // Predict unbalanced asterisks during streaming + if (!isFinal && isOdd(countOccurrences(processedText, '*'))) { + // Add asterisk at the end to balance it + processedText = processedText.trimEnd() + '*'; + } + if (isImpersonate) { $('#send_textarea').val(processedText).trigger('input'); } diff --git a/public/scripts/utils.js b/public/scripts/utils.js index dc84a357d..77763b536 100644 --- a/public/scripts/utils.js +++ b/public/scripts/utils.js @@ -216,3 +216,19 @@ export function end_trim_to_sentence(input, include_newline = false) { return input.substring(0, last + 1).trimEnd(); } + +export function countOccurrences(string, character) { + let count = 0; + + for (let i = 0; i < string.length; i++) { + if (string[i] === character) { + count++; + } + } + + return count; +} + +export function isOdd(number) { + return number % 2 !== 0; +} \ No newline at end of file From 933e5af58f7bc7a36be86e02b8a396db76b60234 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 19 May 2023 23:45:56 +0300 Subject: [PATCH 55/79] Reduce console spam --- server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server.js b/server.js index 66c3291c2..4bfc42268 100644 --- a/server.js +++ b/server.js @@ -147,7 +147,6 @@ const tokenizersCache = {}; function getTiktokenTokenizer(model) { if (tokenizersCache[model]) { - console.log('Using the cached tokenizer instance for', model); return tokenizersCache[model]; } From 8889e5546e9cd810a68963263b138ea0af712d41 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 00:14:02 +0300 Subject: [PATCH 56/79] Fix characters list corruption --- public/script.js | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/public/script.js b/public/script.js index dd77a6e8b..950e0392b 100644 --- a/public/script.js +++ b/public/script.js @@ -227,7 +227,6 @@ let safetychat = [ ]; let chat_create_date = 0; -let prev_selected_char = null; const default_ch_mes = "Hello"; let count_view_mes = 0; let mesStr = ""; @@ -4105,8 +4104,7 @@ function setRightTabSelectedClass(selectedButtonId) { }); } -function select_rm_info(type, charId) { - +function select_rm_info(type, charId, previousCharId = null) { if (!type) { toastr.error(`Invalid process (no 'type')`); return; @@ -4137,10 +4135,8 @@ function select_rm_info(type, charId) { setRightTabSelectedClass(); - prev_selected_char = charId; - - if (prev_selected_char) { - const newId = characters.findIndex((x) => x.name == prev_selected_char); + if (previousCharId) { + const newId = characters.findIndex((x) => x.avatar == previousCharId); if (newId >= 0) { this_chid = newId; } @@ -4247,21 +4243,11 @@ function select_rm_create() { } function select_rm_characters() { - restoreSelectedCharacter(); - menu_type = "characters"; selectRightMenuWithAnimation('rm_characters_block'); setRightTabSelectedClass('rm_button_characters'); } -function restoreSelectedCharacter() { - if (prev_selected_char) { - let newChId = characters.findIndex((x) => x.name == prev_selected_char); - $(`.character_select[chid="${newChId}"]`).trigger("click"); - prev_selected_char = null; - } -} - function setExtensionPrompt(key, value, position, depth) { extension_prompts[key] = { value, position, depth }; } @@ -5392,7 +5378,7 @@ $(document).ready(function () { $("#create_button").attr("value", "✅"); let oldSelectedChar = null; if (this_chid != undefined && this_chid != "invalid-safety-id") { - oldSelectedChar = characters[this_chid].name; + oldSelectedChar = characters[this_chid].avatar; } console.log(`new avatar id: ${html}`); @@ -5402,7 +5388,7 @@ $(document).ready(function () { $("#rm_info_block").transition({ opacity: 0, duration: 0 }); var $prev_img = $("#avatar_div_div").clone(); $("#rm_info_avatar").append($prev_img); - select_rm_info(`char_create`, save_name); + select_rm_info(`char_create`, save_name, oldSelectedChar); $("#rm_info_block").transition({ opacity: 1.0, duration: 2000 }); crop_data = undefined; @@ -6226,8 +6212,6 @@ $(document).ready(function () { return; } - let names = []; - for (const file of e.target.files) { var ext = file.name.match(/\.(\w+)$/); if ( @@ -6264,13 +6248,11 @@ $(document).ready(function () { let oldSelectedChar = null; if (this_chid != undefined && this_chid != "invalid-safety-id") { - oldSelectedChar = characters[this_chid].name; + oldSelectedChar = characters[this_chid].avatar; } - names.push(data.file_name); - let nameString = DOMPurify.sanitize(names.join(', ')); await getCharacters(); - select_rm_info(`char_import`, data.file_name); + select_rm_info(`char_import`, data.file_name, oldSelectedChar); $("#rm_info_block").transition({ opacity: 1, duration: 1000 }); } }, From bb1f22b42c96ec7917262abd1dd5700506035098 Mon Sep 17 00:00:00 2001 From: ouoertheo Date: Fri, 19 May 2023 21:42:50 -0500 Subject: [PATCH 57/79] add elevenlabs multilingual. add tts debug method --- public/scripts/extensions/tts/elevenlabs.js | 12 ++++++++++++ public/scripts/extensions/tts/index.js | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/public/scripts/extensions/tts/elevenlabs.js b/public/scripts/extensions/tts/elevenlabs.js index 65c3cf302..c039156d5 100644 --- a/public/scripts/extensions/tts/elevenlabs.js +++ b/public/scripts/extensions/tts/elevenlabs.js @@ -17,6 +17,7 @@ class ElevenLabsTtsProvider { stability: 0.75, similarity_boost: 0.75, apiKey: "", + multilingual: false, voiceMap: {} } @@ -28,6 +29,10 @@ class ElevenLabsTtsProvider { + ` return html } @@ -36,6 +41,7 @@ class ElevenLabsTtsProvider { // Update dynamically this.settings.stability = $('#elevenlabs_tts_stability').val() this.settings.similarity_boost = $('#elevenlabs_tts_similarity_boost').val() + this.settings.multilingual = $('#elevenlabs_tts_multilingual').prop('checked') } @@ -59,6 +65,7 @@ class ElevenLabsTtsProvider { $('#elevenlabs_tts_stability').val(this.settings.stability) $('#elevenlabs_tts_similarity_boost').val(this.settings.similarity_boost) $('#elevenlabs_tts_api_key').val(this.settings.apiKey) + $('#tts_auto_generation').prop('checked', this.settings.multilingual) console.info("Settings loaded") } @@ -165,6 +172,10 @@ class ElevenLabsTtsProvider { } async fetchTtsGeneration(text, voiceId) { + let model = "eleven_monolingual_v1" + if (this.settings.multilingual == true) { + model = "eleven_multilingual_v1" + } console.info(`Generating new TTS for voice_id ${voiceId}`) const response = await fetch( `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, @@ -175,6 +186,7 @@ class ElevenLabsTtsProvider { 'Content-Type': 'application/json' }, body: JSON.stringify({ + model: model, text: text, voice_settings: this.settings }) diff --git a/public/scripts/extensions/tts/index.js b/public/scripts/extensions/tts/index.js index ba618eaca..d7664e4d2 100644 --- a/public/scripts/extensions/tts/index.js +++ b/public/scripts/extensions/tts/index.js @@ -162,6 +162,23 @@ function isTtsProcessing() { return processing } +function debugTtsPlayback() { + console.log(JSON.stringify( + { + "ttsProviderName": ttsProviderName, + "currentMessageNumber": currentMessageNumber, + "isWorkerBusy":isWorkerBusy, + "audioPaused": audioPaused, + "audioJobQueue": audioJobQueue, + "currentAudioJob": currentAudioJob, + "audioQueueProcessorReady": audioQueueProcessorReady, + "ttsJobQueue": ttsJobQueue, + "currentTtsJob": currentTtsJob, + } + )) +} +window.debugTtsPlayback = debugTtsPlayback + //##################// // Audio Control // //##################// From fef2a62e1cf59c3ca071f63dd8e30d7268620c2d Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 May 2023 12:43:16 +0900 Subject: [PATCH 58/79] modified gitignore to get new config.conf --- ---config.conf | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ---config.conf diff --git a/---config.conf b/---config.conf new file mode 100644 index 000000000..452636cca --- /dev/null +++ b/---config.conf @@ -0,0 +1,24 @@ + +const port = 8000; +const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] +const whitelistMode = true; //Disabling enabling the ip whitelist mode. true/false +const basicAuthMode = false; //Toggle basic authentication for endpoints. +const basicAuthUser = {username: "user", password: "password"}; //Login credentials when basicAuthMode is true. +const disableThumbnails = false; //Disables the generation of thumbnails, opting to use the raw images instead +const autorun = true; //Autorun in the browser. true/false +const enableExtensions = true; //Enables support for TavernAI-extras project +const listen = true; // If true, Can be access from other device or PC. otherwise can be access only from hosting machine. +const allowKeysExposure = false; // If true, private API keys could be fetched to the frontend. + +module.exports = { + port, + whitelist, + whitelistMode, + basicAuthMode, + basicAuthUser, + autorun, + enableExtensions, + listen, + disableThumbnails, + allowKeysExposure, +}; From e8274521ef328094280e9d2b080f2580eeec8a73 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 May 2023 12:43:55 +0900 Subject: [PATCH 59/79] remove temp config file after pull --- ---config.conf | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 ---config.conf diff --git a/---config.conf b/---config.conf deleted file mode 100644 index 452636cca..000000000 --- a/---config.conf +++ /dev/null @@ -1,24 +0,0 @@ - -const port = 8000; -const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] -const whitelistMode = true; //Disabling enabling the ip whitelist mode. true/false -const basicAuthMode = false; //Toggle basic authentication for endpoints. -const basicAuthUser = {username: "user", password: "password"}; //Login credentials when basicAuthMode is true. -const disableThumbnails = false; //Disables the generation of thumbnails, opting to use the raw images instead -const autorun = true; //Autorun in the browser. true/false -const enableExtensions = true; //Enables support for TavernAI-extras project -const listen = true; // If true, Can be access from other device or PC. otherwise can be access only from hosting machine. -const allowKeysExposure = false; // If true, private API keys could be fetched to the frontend. - -module.exports = { - port, - whitelist, - whitelistMode, - basicAuthMode, - basicAuthUser, - autorun, - enableExtensions, - listen, - disableThumbnails, - allowKeysExposure, -}; From f5665f2b7dcbc073989cb68276f494d810a3ffdf Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 May 2023 20:04:26 +0900 Subject: [PATCH 60/79] Update remote connection info in readme.md --- readme.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 1687c59f2..adac7f87f 100644 --- a/readme.md +++ b/readme.md @@ -197,17 +197,27 @@ Now devices which have the IP specified in the file will be able to connect. *Note: `config.conf` also has a `whitelist` array, which you can use in the same way, but this array will be ignored if `whitelist.txt` exists.* -### 2. Connecting to ST from a remote device +### 2. Getting the IP for the ST host machine -After the whitelist has been setup, to connect over wifi you'll need the IP of the ST-hosting device. +After the whitelist has been setup, you'll need the IP of the ST-hosting device. -If the ST-hosting device is on the same wifi network, you will point your remote device's browser to the ST-host's internal wifi IP: +If the ST-hosting device is on the same wifi network, you will use the ST-host's internal wifi IP: * For Windows: windows button > type `cmd.exe` in the search bar > type `ipconfig` in the console, hit Enter > look for `IPv4` listing. If you (or someone else) wants to connect to your hosted ST while not being on the same network, you will need the public IP of your ST-hosting device. -While using the ST-hosting device, access [this page](https://whatismyipaddress.com/) and look for for `IPv4`. This is what you would use to connect from the remote device. +* While using the ST-hosting device, access [this page](https://whatismyipaddress.com/) and look for for `IPv4`. This is what you would use to connect from the remote device. + +### 3. Connect the remote device to the ST host machine. + +Whatever IP you ended up with for your situation, you will put that IP address and port number into the remote device's web browser. + +A typical address for an ST host on the same wifi network would look like: + +`http://192.168.0.5:8000` + +Use http:// NOT https:// ### Opening your ST to all IPs From ca066ca796f31d009db9e0700c33d81eeb0c9b36 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 May 2023 20:05:22 +0900 Subject: [PATCH 61/79] Update remote connections info in readme.md --- readme.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 01d07057f..f92043641 100644 --- a/readme.md +++ b/readme.md @@ -207,17 +207,27 @@ Now devices which have the IP specified in the file will be able to connect. *Note: `config.conf` also has a `whitelist` array, which you can use in the same way, but this array will be ignored if `whitelist.txt` exists.* -### 2. Connecting to ST from a remote device +### 2. Getting the IP for the ST host machine -After the whitelist has been setup, to connect over wifi you'll need the IP of the ST-hosting device. +After the whitelist has been setup, you'll need the IP of the ST-hosting device. -If the ST-hosting device is on the same wifi network, you will point your remote device's browser to the ST-host's internal wifi IP: +If the ST-hosting device is on the same wifi network, you will use the ST-host's internal wifi IP: * For Windows: windows button > type `cmd.exe` in the search bar > type `ipconfig` in the console, hit Enter > look for `IPv4` listing. If you (or someone else) wants to connect to your hosted ST while not being on the same network, you will need the public IP of your ST-hosting device. -While using the ST-hosting device, access [this page](https://whatismyipaddress.com/) and look for for `IPv4`. This is what you would use to connect from the remote device. +* While using the ST-hosting device, access [this page](https://whatismyipaddress.com/) and look for for `IPv4`. This is what you would use to connect from the remote device. + +### 3. Connect the remote device to the ST host machine. + +Whatever IP you ended up with for your situation, you will put that IP address and port number into the remote device's web browser. + +A typical address for an ST host on the same wifi network would look like: + +`http://192.168.0.5:8000` + +Use http:// NOT https:// ### Opening your ST to all IPs From 4b20abc38910e98d80234e9211bc366305ee094f Mon Sep 17 00:00:00 2001 From: Sanskar Tiwari Date: Sat, 20 May 2023 19:37:01 +0530 Subject: [PATCH 62/79] add batch file to update and start --- UpdateAndStart.bat | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 UpdateAndStart.bat diff --git a/UpdateAndStart.bat b/UpdateAndStart.bat new file mode 100644 index 000000000..261f13c33 --- /dev/null +++ b/UpdateAndStart.bat @@ -0,0 +1,16 @@ +@echo off +pushd %~dp0 +git --version > nul 2>&1 +if %errorlevel% neq 0 ( + echo Git is not installed on this system. Skipping update. +) else ( + call git pull + if %errorlevel% neq 0 ( + REM incase we get merge conflicts or something + echo There were errors while updating. Please download the latest version manually. + ) +) +call npm install +node server.js +pause +popd \ No newline at end of file From 9a537c8a14263913a085df75e8dc4aad3ebe49fd Mon Sep 17 00:00:00 2001 From: Sanskar Tiwari Date: Sat, 20 May 2023 21:07:28 +0530 Subject: [PATCH 63/79] add flags, lf, eof newline --- UpdateAndStart.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UpdateAndStart.bat b/UpdateAndStart.bat index 261f13c33..803a8c951 100644 --- a/UpdateAndStart.bat +++ b/UpdateAndStart.bat @@ -4,7 +4,7 @@ git --version > nul 2>&1 if %errorlevel% neq 0 ( echo Git is not installed on this system. Skipping update. ) else ( - call git pull + call git pull --rebase --autostash if %errorlevel% neq 0 ( REM incase we get merge conflicts or something echo There were errors while updating. Please download the latest version manually. From 46e26dbf443e123b25bc017652dfd5f3caad004e Mon Sep 17 00:00:00 2001 From: Sanskar Tiwari Date: Sat, 20 May 2023 21:08:04 +0530 Subject: [PATCH 64/79] add flags, lf, eof newline --- UpdateAndStart.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UpdateAndStart.bat b/UpdateAndStart.bat index 803a8c951..3f1d3a93c 100644 --- a/UpdateAndStart.bat +++ b/UpdateAndStart.bat @@ -6,11 +6,11 @@ if %errorlevel% neq 0 ( ) else ( call git pull --rebase --autostash if %errorlevel% neq 0 ( - REM incase we get merge conflicts or something + REM incase there is still something wrong echo There were errors while updating. Please download the latest version manually. ) ) call npm install node server.js pause -popd \ No newline at end of file +popd From e7cbeba87d9a19db530745e9c386063e28ec991c Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 18:54:33 +0300 Subject: [PATCH 65/79] Fix group chats in docker #350 --- Dockerfile | 2 +- docker/docker-entrypoint.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 86877b19c..4c5f4eb65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ COPY . ./ # Copy default chats, characters and user avatars to .default folder RUN \ - IFS="," RESOURCES="characters,chats,User Avatars,settings.json" && \ + IFS="," RESOURCES="characters,chats,groups,group chats,User Avatars,settings.json" && \ \ echo "*** Store default $RESOURCES in .default ***" && \ for R in $RESOURCES; do mv "public/$R" "public/$R.default"; done && \ diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 1e8a87561..d5192c222 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/sh # Initialize missing user files -IFS="," RESOURCES="characters,chats,User Avatars,settings.json" +IFS="," RESOURCES="characters,groups,group chats,chats,User Avatars,settings.json" for R in $RESOURCES; do if [ ! -e "config/$R" ]; then echo "Resource not found, copying from defaults: $R" From b4d04dfdaaea1fc3530967ae32318f4bdb64f14a Mon Sep 17 00:00:00 2001 From: Cohee Date: Sat, 20 May 2023 19:00:20 +0300 Subject: [PATCH 66/79] Update bug_report.md --- .github/ISSUE_TEMPLATE/bug_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2dd35f857..e95525363 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,6 +7,8 @@ assignees: '' --- +> **Warning**. Complete **all** the fields below. Otherwise your bug report will be **ignored**! + **Describe the bug** A clear and concise description of what the bug is. From 06d980b0a7c39f903d2fde445c798c7c697d1297 Mon Sep 17 00:00:00 2001 From: Sanskar Tiwari Date: Sat, 20 May 2023 22:14:59 +0530 Subject: [PATCH 67/79] update documents --- .github/ISSUE_TEMPLATE/bug_report.md | 5 ++++- .github/ISSUE_TEMPLATE/feature_request.md | 3 +++ Update-Instructions.txt | 1 + readme.md | 10 +++++----- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e95525363..572056eca 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: "Create a report to help us improve. PAY ATTENTION: Support requests for extenal programs (reverse proxies, 3rd party servers, other peoples' forks) will be refused!" +about: "Create a report to help us improve. PAY ATTENTION: Support requests for external programs (reverse proxies, 3rd party servers, other peoples' forks) will be refused!" title: "[BUG]" labels: '' assignees: '' @@ -9,6 +9,9 @@ assignees: '' > **Warning**. Complete **all** the fields below. Otherwise your bug report will be **ignored**! +**Have you searched for similar [bugs](https://github.com/Cohee1207/SillyTavern/issues?q=)?** +Yes/No + **Describe the bug** A clear and concise description of what the bug is. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7e3a2deab..ad2eb1b2b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,6 +7,9 @@ assignees: '' --- +**Have you searched for similar [requests](https://github.com/Cohee1207/SillyTavern/issues?q=)?** +Yes/No + **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] diff --git a/Update-Instructions.txt b/Update-Instructions.txt index 3864006aa..9a110b580 100644 --- a/Update-Instructions.txt +++ b/Update-Instructions.txt @@ -16,6 +16,7 @@ Method 1 - GIT We always recommend users install using 'git'. Here's why: When you have installed via `git clone`, all you have to do to update is type `git pull` in a command line in the ST folder. +You can also try running the 'UpdateAndStart.bat' file, which will almost do the same thing. (Windows only) Alternatively, if the command prompt gives you problems (and you have GitHub Desktop installed), you can use the 'Repository' menu and select 'Pull'. The updates are applied automatically and safely. diff --git a/readme.md b/readme.md index adac7f87f..85cc7f8a1 100644 --- a/readme.md +++ b/readme.md @@ -148,10 +148,10 @@ Easy to follow guide with pretty pictures: Installing via zip download - 1. install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended) - 2. download the zip from this GitHub repo - 3. unzip it into a folder of your choice - 4. run start.bat via double-clicking or in a command line. + 1. Install [NodeJS](https://nodejs.org/en) (latest LTS version is recommended) + 2. Download the zip from this GitHub repo. (Get the `Source code (zip)` from [Releases](https://github.com/Cohee1207/SillyTavern/releases/latest)) + 3. Unzip it into a folder of your choice + 4. Run `Start.bat` via double-clicking or in a command line. 5. Once the server has prepared everything for you, it will open a tab in your browser. ### Linux @@ -221,7 +221,7 @@ Use http:// NOT https:// ### Opening your ST to all IPs -We do not reccomend doing this, but you can open `config.conf` and change `whitelist` to `false`. +We do not recommend doing this, but you can open `config.conf` and change `whitelist` to `false`. You must remove (or rename) `whitelist.txt` in the SillyTavern base install folder, if it exists. From db6dad5b2d4e23fb137fd72f82c344166d725a35 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 19:54:27 +0300 Subject: [PATCH 68/79] Fix prompting with bias and names --- public/script.js | 26 +++++++++++--------------- public/scripts/power-user.js | 9 +++++++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/public/script.js b/public/script.js index 950e0392b..2b86e0f1f 100644 --- a/public/script.js +++ b/public/script.js @@ -1367,7 +1367,13 @@ export function extractMessageBias(message) { found.push(curMatch[1].trim()); } - return ` ${found.join(" ")} `; + let biasString = ''; + + if (found.length) { + biasString = ` ${found.join(" ")} ` + } + + return biasString; } function cleanGroupMessage(getMessage) { @@ -1705,8 +1711,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, return; } - streamingProcessor = isStreamingEnabled() ? new StreamingProcessor(type, force_name2) : false; - // Hide swipes on either multigen or real streaming if (isStreamingEnabled() || isMultigenEnabled()) { hideSwipeButtons(); @@ -1814,8 +1818,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, storyString += appendToStoryString(Scenario, power_user.disable_scenario_formatting ? '' : 'Circumstances and context of the dialogue: '); } - // Pygmalion does that anyway - if (promptBias || (power_user.always_force_name2 && !is_pygmalion)) { + if (promptBias || power_user.always_force_name2 || is_pygmalion) { force_name2 = true; } @@ -1928,6 +1931,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, let mesSend = []; console.log('calling runGenerate'); + streamingProcessor = isStreamingEnabled() ? new StreamingProcessor(type, force_name2) : false; await runGenerate(); async function runGenerate(cycleGenerationPromt = '') { @@ -1960,14 +1964,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, } } if (is_pygmalion && !isInstruct) { - if (i === arrMes.length - 1 && item.trim().startsWith(name1 + ":")) {//for add name2 when user sent - item = item + name2 + ":"; - } - if (i === arrMes.length - 1 && !item.trim().startsWith(name1 + ":")) {//for add name2 when continue - if (textareaText == "") { - item = item + '\n' + name2 + ":"; - } - } if (item.trim().startsWith(name1)) { item = item.replace(name1 + ':', 'You:'); } @@ -2026,7 +2022,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, // Get instruct mode line if (isInstruct && tokens_already_generated === 0) { const name = isImpersonate ? (is_pygmalion ? 'You' : name1) : name2; - mesSendString += formatInstructModePrompt(name, isImpersonate); + mesSendString += formatInstructModePrompt(name, isImpersonate, promptBias); } // Get non-instruct impersonation line @@ -2039,7 +2035,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, } // Add character's name - if (force_name2 && tokens_already_generated === 0) { + if (!isInstruct && force_name2 && tokens_already_generated === 0) { if (!mesSendString.endsWith('\n')) { mesSendString += '\n'; } diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js index 2f76b50da..b67bc1afd 100644 --- a/public/scripts/power-user.js +++ b/public/scripts/power-user.js @@ -661,11 +661,16 @@ export function formatInstructStoryString(story) { return text; } -export function formatInstructModePrompt(name, isImpersonate) { +export function formatInstructModePrompt(name, isImpersonate, promptBias) { const includeNames = power_user.instruct.names || !!selected_group; const sequence = isImpersonate ? power_user.instruct.input_sequence : power_user.instruct.output_sequence; const separator = power_user.instruct.wrap ? '\n' : ''; - const text = includeNames ? (separator + sequence + separator + `${name}:`) : (separator + sequence); + let text = includeNames ? (separator + sequence + separator + `${name}:`) : (separator + sequence); + + if (!isImpersonate && promptBias) { + text += (includeNames ? promptBias : (separator + promptBias)); + } + return text.trimEnd(); } From e58360a4b4e960e644fec283c3c1b947a36b9e9f Mon Sep 17 00:00:00 2001 From: Sanskar Tiwari Date: Sun, 21 May 2023 02:03:09 +0530 Subject: [PATCH 69/79] subsitute user and char variable in world info keywords --- public/scripts/world-info.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index 1ec51b112..89e16be83 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -506,16 +506,18 @@ function checkWorldInfo(chat) { if (Array.isArray(entry.key) && entry.key.length) { primary: for (let key of entry.key) { - if (key && textToScan.includes(key.trim().toLowerCase())) { + const substituted = substituteParams(key); + if (substituted && textToScan.includes(substituted.trim().toLowerCase())) { if ( entry.selective && Array.isArray(entry.keysecondary) && entry.keysecondary.length ) { secondary: for (let keysecondary of entry.keysecondary) { + const secondarySubstituted = substituteParams(keysecondary); if ( - keysecondary && - textToScan.includes(keysecondary.trim().toLowerCase()) + secondarySubstituted && + textToScan.includes(secondarySubstituted.trim().toLowerCase()) ) { activatedNow.add(entry.uid); break secondary; @@ -685,4 +687,4 @@ $(document).ready(() => { world_info_recursive = !!$(this).prop('checked'); saveSettingsDebounced(); }) -}); \ No newline at end of file +}); From 6c2b72ac7f157a473273e84e16f6ffeacd373005 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 23:35:39 +0300 Subject: [PATCH 70/79] Add date & time substitution params. #155 --- public/script.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 2b86e0f1f..9a2d91a48 100644 --- a/public/script.js +++ b/public/script.js @@ -1268,6 +1268,8 @@ function substituteParams(content, _name1, _name2) { content = content.replace(/{{char}}/gi, _name2); content = content.replace(//gi, _name1); content = content.replace(//gi, _name2); + content = content.replace(/{{time}}/gi, moment().format('LT')); + content = content.replace(/{{date}}/gi, moment().format('LL')); return content; } @@ -1370,7 +1372,7 @@ export function extractMessageBias(message) { let biasString = ''; if (found.length) { - biasString = ` ${found.join(" ")} ` + biasString = ` ${found.join(" ")}` } return biasString; From ba5f5c272a35869d6d42e5fbdecf971b33236d0f Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 23:40:21 +0300 Subject: [PATCH 71/79] Add datetime substitutions to the guidebook --- public/notes/content.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/notes/content.md b/public/notes/content.md index 2ebdcd8cd..6f44cb7db 100644 --- a/public/notes/content.md +++ b/public/notes/content.md @@ -136,6 +136,8 @@ _A list of tags that are replaced when sending to generate:_ 1. {{user}} and <USER> are replaced by the User's Name 2. {{char}} and <BOT> are replaced by the Character's Name +3. {{time}} is replaced with the current system time. +4. {{date}} is replaced with the current system date. ### Favorite Character From 299b9a04bcd57a38cce309b7aa2395f8a1bd8a6e Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 20 May 2023 23:59:39 +0300 Subject: [PATCH 72/79] Replace info popups with toasts --- public/script.js | 11 +++-------- public/scripts/bookmarks.js | 2 +- public/scripts/extensions/stable-diffusion/index.js | 4 ++-- public/scripts/group-chats.js | 4 ++-- public/scripts/horde.js | 2 +- public/scripts/openai.js | 12 ++++++------ public/scripts/world-info.js | 2 +- 7 files changed, 16 insertions(+), 21 deletions(-) diff --git a/public/script.js b/public/script.js index 9a2d91a48..9d99c08ef 100644 --- a/public/script.js +++ b/public/script.js @@ -1703,7 +1703,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, } if (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming && !textgenerationwebui_settings.streaming_url) { - callPopup('Streaming URL is not set. Look it up in the console window when starting TextGen Web UI', 'text'); + toastr.error('Streaming URL is not set. Look it up in the console window when starting TextGen Web UI'); is_send_press = false; return; } @@ -2998,11 +2998,6 @@ function extractMessageFromData(data) { if (main_api == 'textgenerationwebui') { getMessage = data.results[0].text; - if (getMessage == null || data.error) { - activateSendButtons(); - callPopup('

Got empty response from Text generation web UI. Try restarting the API with recommended options.

', 'text'); - return; - } } if (main_api == 'novel') { @@ -4520,7 +4515,7 @@ function setGenerationProgress(progress) { function isHordeGenerationNotAllowed() { if (main_api == "kobold" && horde_settings.use_horde && preset_settings == "gui") { - callPopup('GUI Settings preset is not supported for Horde. Please select another preset.', 'text'); + toastr.error('GUI Settings preset is not supported for Horde. Please select another preset.'); return true; } @@ -5587,7 +5582,7 @@ $(document).ready(function () { let value = formatKoboldUrl($.trim($("#api_url_text").val())); if (!value) { - callPopup('Please enter a valid URL.', 'text'); + toastr.error('Please enter a valid URL.'); return; } diff --git a/public/scripts/bookmarks.js b/public/scripts/bookmarks.js index df8c41014..cf39397c6 100644 --- a/public/scripts/bookmarks.js +++ b/public/scripts/bookmarks.js @@ -266,7 +266,7 @@ async function convertSoloToGroupChat() { $(`.group_select[grid="${group.id}"]`).click(); await delay(1); - callPopup('The chat has been successfully converted!', 'text'); + toastr.success('The chat has been successfully converted!'); } $(document).ready(function () { diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index f26a5a03f..1cadb1292 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -414,7 +414,7 @@ async function generatePicture(_, trigger, message, callback) { } if (!modules.includes('sd') && !extension_settings.sd.horde) { - callPopup("Extensions API is not connected or doesn't provide SD module. Enable Stable Horde to generate images.", 'text'); + toastr.warning("Extensions API is not connected or doesn't provide SD module. Enable Stable Horde to generate images."); return; } @@ -545,7 +545,7 @@ async function generateHordeImage(prompt, callback) { const base64Image = `data:image/webp;base64,${data}`; callback ? callback(prompt, base64Image) : sendMessage(prompt, base64Image); } else { - callPopup('Image generation has failed. Please try again.', 'text'); + toastr.error('Image generation has failed. Please try again.'); } } diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 65f33cc14..90f189f1f 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -480,7 +480,7 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { activatedMembers = activateSwipe(group.members); if (activatedMembers.length === 0) { - callPopup('

Deleted group member swiped. To get a reply, add them back to the group.

', 'text'); + toastr.warning('Deleted group member swiped. To get a reply, add them back to the group.'); throw new Error('Deleted group member swiped'); } } @@ -961,7 +961,7 @@ function select_group_chats(groupId, skipAnimation) { $("#rm_group_delete").off(); $("#rm_group_delete").on("click", function () { if (is_group_generating) { - callPopup('

Not so fast! Wait for the characters to stop typing before deleting the group.

', 'text'); + toastr.warning('Not so fast! Wait for the characters to stop typing before deleting the group.'); return; } diff --git a/public/scripts/horde.js b/public/scripts/horde.js index 95532261f..348dd2ae7 100644 --- a/public/scripts/horde.js +++ b/public/scripts/horde.js @@ -41,7 +41,7 @@ function validateHordeModel() { let selectedModels = models.filter(m => horde_settings.models.includes(m.name)); if (selectedModels.length === 0) { - callPopup('No Horde model selected or the selected models are no longer available. Please choose another model', 'text'); + toastr.warning('No Horde model selected or the selected models are no longer available. Please choose another model'); throw new Error('No Horde model available'); } diff --git a/public/scripts/openai.js b/public/scripts/openai.js index bc35e3b05..e336ff532 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -146,7 +146,7 @@ function validateReverseProxy() { new URL(oai_settings.reverse_proxy); } catch (err) { - callPopup('Entered reverse proxy address is not a valid URL', 'text'); + toastr.error('Entered reverse proxy address is not a valid URL'); setOnlineStatus('no_connection'); resultCheckStatusOpen(); throw err; @@ -930,7 +930,7 @@ async function showApiKeyUsage() { } catch (err) { console.error(err); - callPopup('Invalid API key', 'text'); + toastr.error('Invalid API key'); } } @@ -995,7 +995,7 @@ async function createNewLogitBiasPreset() { } if (name in oai_settings.bias_presets) { - callPopup('Preset name should be unique.', 'text'); + toastr.error('Preset name should be unique.'); return; } @@ -1032,12 +1032,12 @@ async function onLogitBiasPresetImportFileChange(e) { e.target.value = ''; if (name in oai_settings.bias_presets) { - callPopup('Preset name should be unique.', 'text'); + toastr.error('Preset name should be unique.'); return; } if (!Array.isArray(importedFile)) { - callPopup('Invalid logit bias preset file.', 'text'); + toastr.error('Invalid logit bias preset file.'); return; } @@ -1341,7 +1341,7 @@ $(document).ready(function () { $("#update_oai_preset").on('click', async function () { const name = oai_settings.preset_settings_openai; await saveOpenAIPreset(name, oai_settings); - callPopup('Preset updated', 'text'); + toastr.success('Preset updated'); }); $("#main_prompt_restore").on('click', function () { diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index 7911cb5ed..1effa42f4 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -80,7 +80,7 @@ function setWorldInfoSettings(settings, data) { // World Info Editor async function showWorldEditor() { if (!world_info) { - callPopup("

Select a world info first!

", "text"); + toastr.warning("Select a world info first!"); return; } From 285d3e3d4ae889bf05e7d21ff65146196e6e5b12 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 21 May 2023 00:40:13 +0300 Subject: [PATCH 73/79] Fix LLAMA tokenization. Add case-sensitive WI matching --- public/index.html | 15 ++++++++--- public/notes/content.md | 52 +++++++++++++++++++++--------------- public/script.js | 11 ++++---- public/scripts/world-info.js | 29 +++++++++++++------- 4 files changed, 68 insertions(+), 39 deletions(-) diff --git a/public/index.html b/public/index.html index 6b013b369..511f059ee 100644 --- a/public/index.html +++ b/public/index.html @@ -1458,7 +1458,7 @@
-
+
+
@@ -2195,7 +2204,7 @@

Context Template Editor

- +
Substitution Parameters @@ -2632,4 +2641,4 @@ - \ No newline at end of file + diff --git a/public/notes/content.md b/public/notes/content.md index 6f44cb7db..e2b64c967 100644 --- a/public/notes/content.md +++ b/public/notes/content.md @@ -16,7 +16,7 @@ Usually it all takes 200-350 tokens. For most Kobold's models the easiest way is to use a free form for description, and in each sentence it is desirable to specify the name of the character. -The entire description should be in one line without hyphenation. +The entire description should be in one line without hyphenation. For example: @@ -96,15 +96,15 @@ Another example: ### First message -The First Message is an important thing that sets exactly how and in what style the character will communicate. +The First Message is an important thing that sets exactly how and in what style the character will communicate. -It is desirable that the character's first message be long, so that later it would be less likely that the character would respond in with very short messages. +It is desirable that the character's first message be long, so that later it would be less likely that the character would respond in with very short messages. You can also use asterisks ** to describe the character's actions. For example: -`*I noticed you came inside, I walked up and stood right in front of you* Welcome. I'm glad to see you here. *I said with toothy smug sunny smile looking you straight in the eye* What brings you...` +`*I noticed you came inside, I walked up and stood right in front of you* Welcome. I'm glad to see you here. *I said with toothy smug sunny smile looking you straight in the eye* What brings you...` ### Examples of dialogue @@ -116,13 +116,13 @@ Example: ``` -{{user}}: Hi Aqua, I heard you like to spend time in the pub. -{{char}}: *excitedly* Oh my goodness, yes! I just love spending time at the pub! It's so much fun to talk to all the adventurers and hear about their exciting adventures! And you are? -{{user}}: I'm a new here and I wanted to ask for your advice. -{{char}}: *giggles* Oh, advice! I love giving advice! And in gratitude for that, treat me to a drink! *gives signals to the bartender* +{{user}}: Hi Aqua, I heard you like to spend time in the pub. +{{char}}: *excitedly* Oh my goodness, yes! I just love spending time at the pub! It's so much fun to talk to all the adventurers and hear about their exciting adventures! And you are? +{{user}}: I'm a new here and I wanted to ask for your advice. +{{char}}: *giggles* Oh, advice! I love giving advice! And in gratitude for that, treat me to a drink! *gives signals to the bartender* -{{user}}: Hello +{{user}}: Hello {{char}}: *excitedly* Hello there, dear! Are you new to Axel? Don't worry, I, Aqua the goddess of water, am here to help you! Do you need any assistance? And may I say, I look simply radiant today! *strikes a pose and looks at you with puppy eyes* ``` @@ -134,7 +134,7 @@ Circumstances and context of the dialogue. _A list of tags that are replaced when sending to generate:_ -1. {{user}} and <USER> are replaced by the User's Name +1. {{user}} and <USER> are replaced by the User's Name 2. {{char}} and <BOT> are replaced by the Character's Name 3. {{time}} is replaced with the current system time. 4. {{date}} is replaced with the current system date. @@ -163,7 +163,7 @@ _It is important to note that while World Info helps guide the AI towards your d #### Key -A list of keywords that trigger the activation of a World Info entry. +A list of keywords that trigger the activation of a World Info entry. Keys are not case-sensitive by default (this is [configurable](#casesensitivekeys)). #### Secondary Key @@ -234,6 +234,14 @@ Content: Rufus is a dog. **Both** of them will be pulled into the context if the message text mentions **just Bessie**. +### Case-sensitive keys + +**To get pulled into the context, entry keys need to match the case as they are defined in the World Info entry.** + +This is useful when your keys are common words or parts of common words. + +For example, when this setting is active, keys 'rose' and 'Rose' will be treated differently, depending on the inputs. + ## KoboldAI ### Basic Settings @@ -258,7 +266,7 @@ The maximum amount of tokens that the AI will generate to respond. One word is a #### Context size -How much will the AI remember. Context size also affects the speed of generation. +How much will the AI remember. Context size also affects the speed of generation. _Important_: The setting of Context Size in SillyTavern GUI overrides the setting for KoboldAI GUI @@ -323,10 +331,10 @@ They are created by training the AI with a special type of prompt using a collec To get a NovelAI API key, follow these instructions: -1. Go to the NovelAI website and Login. -2. Create a new story, or open an existing story. -3. Open the Network Tools on your web browser. (For Chrome or Firefox, you do this by pressing Ctrl+Shift+I, then switching to the Network tab.) -4. Generate something. You should see two requests to [api.novelai.net/ai/generate-stream](http://api.novelai.net/ai/generate-stream), which might look something like this: +1. Go to the NovelAI website and Login. +2. Create a new story, or open an existing story. +3. Open the Network Tools on your web browser. (For Chrome or Firefox, you do this by pressing Ctrl+Shift+I, then switching to the Network tab.) +4. Generate something. You should see two requests to [api.novelai.net/ai/generate-stream](http://api.novelai.net/ai/generate-stream), which might look something like this: ![1.png](1.png) @@ -340,7 +348,7 @@ The long string (after "Bearer", not including it) is your API key. ### Settings -The files with the settings are here (SillyTavern\public\NovelAI Settings). +The files with the settings are here (SillyTavern\public\NovelAI Settings). You can also manually add your own settings files. #### Temperature @@ -510,12 +518,12 @@ Overrides the default separators controlled by "Disable example chats formatting #### Disable example chats formatting -`` won't be added at the beginning of each example message block. +`` won't be added at the beginning of each example message block. _(If custom separator is not set)_ #### Disable chat start formatting -`` won't be added between the character card and the chat log. +`` won't be added between the character card and the chat log. _(If custom separator is not set)_ #### Always add character's name to prompt @@ -538,12 +546,12 @@ Has no effect. #### Disable example chats formatting -`This is how **Character** should talk` won't be added at the beginning of each example message block. +`This is how **Character** should talk` won't be added at the beginning of each example message block. _(If custom separator is not set)_ #### Disable chat start formatting -`Then the roleplay chat between **User** and **Character** begins` won't be added between the character card and the chat log. +`Then the roleplay chat between **User** and **Character** begins` won't be added between the character card and the chat log. _(If custom separator is not set)_ #### Always add character's name to prompt @@ -552,7 +560,7 @@ Appends character's name to the prompt to force the model to complete the messag ``` ** OTHER CONTEXT HERE ** -Character: +Character: ``` ## Group Chats diff --git a/public/script.js b/public/script.js index 9d99c08ef..7551ab3e9 100644 --- a/public/script.js +++ b/public/script.js @@ -296,7 +296,7 @@ const system_messages = {
  • {​{text}​} - sets a one-time behavioral bias for the AI. Resets when you send the next message.
  • - Hotkeys/Keybinds: + Hotkeys/Keybinds:
    • Up = Edit last message in chat
    • Ctrl+Up = Edit last USER message in chat
    • @@ -458,7 +458,7 @@ function getTokenCount(str, padding = undefined) { jQuery.ajax({ async: false, type: 'POST', // - url: `/ tokenize_llama`, + url: `/tokenize_llama`, data: JSON.stringify({ text: str }), dataType: "json", contentType: "application/json", @@ -2434,7 +2434,7 @@ function getMaxContextSize() { if (novel_tier === 1) { this_max_context = 1024; } else { - this_max_context = 2048 - 60; //fix for fat tokens + this_max_context = 2048 - 60; //fix for fat tokens if (nai_settings.model_novel == 'krake-v2') { this_max_context -= 160; } @@ -2715,7 +2715,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
      World Info:
      ${worldInfoStringTokens}
    -
    +
    Chat History:
    ${ActualChatHistoryTokens}
    @@ -2802,7 +2802,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
    World Info:
    ${worldInfoStringTokens}
    -
    +
    Chat History:
    ${ActualChatHistoryTokens}
    @@ -3852,6 +3852,7 @@ async function saveSettings(type) { world_info_depth: world_info_depth, world_info_budget: world_info_budget, world_info_recursive: world_info_recursive, + world_info_case_sensitive: world_info_case_sensitive, textgenerationwebui_settings: textgenerationwebui_settings, swipes: swipes, horde_settings: horde_settings, diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index b6b8bd40a..20277f10b 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -7,6 +7,7 @@ export { world_info_budget, world_info_depth, world_info_recursive, + world_info_case_sensitive, world_names, imported_world_name, checkWorldInfo, @@ -23,6 +24,7 @@ let world_info_depth = 2; let world_info_budget = 128; let is_world_edit_open = false; let world_info_recursive = false; +let world_info_case_sensitive = false; let imported_world_name = ""; const saveWorldDebounced = debounce(async () => await _save(), 500); const saveSettingsDebounced = debounce(() => saveSettings(), 500); @@ -51,6 +53,8 @@ function setWorldInfoSettings(settings, data) { world_info_budget = Number(settings.world_info_budget); if (settings.world_info_recursive !== undefined) world_info_recursive = Boolean(settings.world_info_recursive); + if (settings.world_info_case_sensitive !== undefined) + world_info_case_sensitive = Boolean(settings.world_info_case_sensitive); $("#world_info_depth_counter").text(world_info_depth); $("#world_info_depth").val(world_info_depth); @@ -59,6 +63,7 @@ function setWorldInfoSettings(settings, data) { $("#world_info_budget").val(world_info_budget); $("#world_info_recursive").prop('checked', world_info_recursive); + $("#world_info_case_sensitive").prop('checked', world_info_case_sensitive); world_names = data.world_names?.length ? data.world_names : []; @@ -476,13 +481,18 @@ async function createNewWorldInfo() { } } +// Gets a string that respects the case sensitivity setting +function transformString(str) { + return world_info_case_sensitive ? str : str.toLowerCase(); +} + function checkWorldInfo(chat) { if (world_info_data.entries.length == 0) { return ""; } const messagesToLookBack = world_info_depth * 2; - let textToScan = chat.slice(0, messagesToLookBack).join("").toLowerCase(); + let textToScan = transformString(chat.slice(0, messagesToLookBack).join("")); let worldInfoBefore = ""; let worldInfoAfter = ""; let needsToScan = true; @@ -507,7 +517,7 @@ function checkWorldInfo(chat) { if (Array.isArray(entry.key) && entry.key.length) { primary: for (let key of entry.key) { const substituted = substituteParams(key); - if (substituted && textToScan.includes(substituted.trim().toLowerCase())) { + if (substituted && textToScan.includes(transformString(substituted.trim()))) { if ( entry.selective && Array.isArray(entry.keysecondary) && @@ -517,7 +527,7 @@ function checkWorldInfo(chat) { const secondarySubstituted = substituteParams(keysecondary); if ( secondarySubstituted && - textToScan.includes(secondarySubstituted.trim().toLowerCase()) + textToScan.includes(transformString(secondarySubstituted.trim())) ) { activatedNow.add(entry.uid); break secondary; @@ -557,11 +567,7 @@ function checkWorldInfo(chat) { } if (needsToScan) { - textToScan = - newEntries - .map((x) => x.content) - .join("\n") - .toLowerCase() + textToScan; + textToScan = (transformString(newEntries.map(x => x.content).join('\n')) + textToScan); } allActivatedEntries = new Set([...allActivatedEntries, ...activatedNow]); @@ -583,7 +589,7 @@ function selectImportedWorldInfo() { imported_world_name = ""; } -$(document).ready(() => { +jQuery(() => { $("#world_info").change(async function () { const selectedWorld = $("#world_info").find(":selected").val(); world_info = null; @@ -688,4 +694,9 @@ $(document).ready(() => { world_info_recursive = !!$(this).prop('checked'); saveSettingsDebounced(); }) + + $('#world_info_case_sensitive').on('input', function () { + world_info_case_sensitive = !!$(this).prop('checked'); + saveSettingsDebounced(); + }) }); From f0c7c96d3c25707ab8463f0694672361e9acb2ae Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 21 May 2023 01:36:35 +0300 Subject: [PATCH 74/79] Added switch to unbrick streaming on some unsupported proxies --- public/index.html | 13 ++++++++++++- public/scripts/openai.js | 37 +++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/public/index.html b/public/index.html index fe3b2d347..df8c33efc 100644 --- a/public/index.html +++ b/public/index.html @@ -366,6 +366,17 @@
    +
    +
    + +
    +
    + Enable this if the streaming doesn't work with your proxy. +
    +
    Context Size (tokens) @@ -2489,4 +2500,4 @@
    - \ No newline at end of file + diff --git a/public/scripts/openai.js b/public/scripts/openai.js index 82a0c7849..ef5f41cd6 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -101,6 +101,7 @@ const default_settings = { openai_model: 'gpt-3.5-turbo', jailbreak_system: false, reverse_proxy: '', + legacy_streaming: false, }; const oai_settings = { @@ -125,6 +126,7 @@ const oai_settings = { openai_model: 'gpt-3.5-turbo', jailbreak_system: false, reverse_proxy: '', + legacy_streaming: false, }; let openai_setting_names; @@ -561,13 +563,19 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) { let response = decoder.decode(value); tryParseStreamingError(response); - + + let eventList = []; + // ReadableStream's buffer is not guaranteed to contain full SSE messages as they arrive in chunks // We need to buffer chunks until we have one or more full messages (separated by double newlines) - messageBuffer += response; - let eventList = messageBuffer.split("\n\n"); - // Last element will be an empty string or a leftover partial message - messageBuffer = eventList.pop(); + if (!oai_settings.legacy_streaming) { + messageBuffer += response; + eventList = messageBuffer.split("\n\n"); + // Last element will be an empty string or a leftover partial message + messageBuffer = eventList.pop(); + } else { + eventList = response.split("\n"); + } for (let event of eventList) { if (!event.startsWith("data")) @@ -624,7 +632,7 @@ async function calculateLogitBias() { function countTokens(messages, full = false) { let chatId = 'undefined'; - + try { if (selected_group) { chatId = groups.find(x => x.id == selected_group)?.chat_id; @@ -656,7 +664,7 @@ function countTokens(messages, full = false) { else { jQuery.ajax({ async: false, - type: 'POST', // + type: 'POST', // url: `/tokenize_openai?model=${oai_settings.openai_model}`, data: JSON.stringify([message]), dataType: "json", @@ -703,6 +711,7 @@ function loadOpenAISettings(data, settings) { oai_settings.openai_max_tokens = settings.openai_max_tokens ?? default_settings.openai_max_tokens; oai_settings.bias_preset_selected = settings.bias_preset_selected ?? default_settings.bias_preset_selected; oai_settings.bias_presets = settings.bias_presets ?? default_settings.bias_presets; + oai_settings.legacy_streaming = settings.legacy_streaming ?? default_settings.legacy_streaming; if (settings.nsfw_toggle !== undefined) oai_settings.nsfw_toggle = !!settings.nsfw_toggle; if (settings.keep_example_dialogue !== undefined) oai_settings.keep_example_dialogue = !!settings.keep_example_dialogue; @@ -726,6 +735,7 @@ function loadOpenAISettings(data, settings) { $('#wrap_in_quotes').prop('checked', oai_settings.wrap_in_quotes); $('#nsfw_first').prop('checked', oai_settings.nsfw_first); $('#jailbreak_system').prop('checked', oai_settings.jailbreak_system); + $('#legacy_streaming').prop('checked', oai_settings.legacy_streaming); if (settings.main_prompt !== undefined) oai_settings.main_prompt = settings.main_prompt; if (settings.nsfw_prompt !== undefined) oai_settings.nsfw_prompt = settings.nsfw_prompt; @@ -774,8 +784,8 @@ async function getStatusOpen() { }; return jQuery.ajax({ - type: 'POST', // - url: '/getstatus_openai', // + type: 'POST', // + url: '/getstatus_openai', // data: JSON.stringify(data), beforeSend: function () { if (oai_settings.reverse_proxy) { @@ -845,6 +855,7 @@ async function saveOpenAIPreset(name, settings) { jailbreak_system: settings.jailbreak_system, impersonation_prompt: settings.impersonation_prompt, bias_preset_selected: settings.bias_preset_selected, + legacy_streaming: settings.legacy_streaming, }; const savePresetSettings = await fetch(`/savepreset_openai?name=${name}`, { @@ -1108,6 +1119,7 @@ function onSettingsPresetChange() { jailbreak_prompt: ['#jailbreak_prompt_textarea', 'jailbreak_prompt', false], impersonation_prompt: ['#impersonation_prompt_textarea', 'impersonation_prompt', false], bias_preset_selected: ['#openai_logit_bias_preset', 'bias_preset_selected', false], + legacy_streaming: ['#legacy_streaming', 'legacy_streaming', false], }; for (const [key, [selector, setting, isCheckbox]] of Object.entries(settingsToUpdate)) { @@ -1169,7 +1181,7 @@ function onReverseProxyInput() { async function onConnectButtonClick(e) { e.stopPropagation(); const api_key_openai = $('#api_key_openai').val().trim(); - + if (api_key_openai.length) { await writeSecret(SECRET_KEYS.OPENAI, api_key_openai); } @@ -1328,6 +1340,11 @@ $(document).ready(function () { saveSettingsDebounced(); }); + $('#legacy_streaming').on('input', function () { + oai_settings.legacy_streaming = !!$(this).prop('checked'); + saveSettingsDebounced(); + }); + $("#api_button_openai").on('click', onConnectButtonClick); $("#openai_reverse_proxy").on('input', onReverseProxyInput); $("#model_openai_select").on('change', onModelChange); From 71d1688dfacd97663d9a5a1f66a0bd036cd70480 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 21 May 2023 02:55:47 +0300 Subject: [PATCH 75/79] View Horde kudos --- public/index.html | 5 +- public/scripts/horde.js | 25 +++++++++- server.js | 106 ++++++++++++++++++++++++---------------- 3 files changed, 92 insertions(+), 44 deletions(-) diff --git a/public/index.html b/public/index.html index 3e8bdce27..b21b09761 100644 --- a/public/index.html +++ b/public/index.html @@ -1023,6 +1023,9 @@
    Get it here: Register
    Enter 0000000000 to use anonymous mode.
    +
    @@ -2644,7 +2647,7 @@ - + \ No newline at end of file diff --git a/public/script.js b/public/script.js index 7551ab3e9..5b0b5cc35 100644 --- a/public/script.js +++ b/public/script.js @@ -5667,15 +5667,20 @@ $(document).ready(function () { var id = $(this).attr("id"); if (id == "option_toggle_AN") { - if (selected_group || this_chid !== undefined && $("#floatingPrompt").css("display") === 'none') { + if (selected_group || this_chid !== undefined + && $("#floatingPrompt").css("display") !== 'flex') { $("#floatingPrompt").css("display", "flex"); $("#floatingPrompt").css("opacity", 0.0); $("#floatingPrompt").transition({ opacity: 1.0, - duration: animation_duration, + duration: 250, easing: animation_easing, }); - $("#ANBlockToggle").click(); + if ($("#ANBlockToggle") + .siblings('.inline-drawer-content') + .css('display') !== 'block') { + $("#ANBlockToggle").click(); + } } else { $("#floatingPrompt").transition({ opacity: 0.0, diff --git a/public/scripts/extensions/floating-prompt/manifest.json b/public/scripts/extensions/floating-prompt/manifest.json index 64fac1b56..edcacbc74 100644 --- a/public/scripts/extensions/floating-prompt/manifest.json +++ b/public/scripts/extensions/floating-prompt/manifest.json @@ -1,5 +1,5 @@ { - "display_name": "Author's Note / Character Bias", + "display_name": "Author's Note (Located in Lower Left Options Menu)", "loading_order": 1, "requires": [], "optional": [], From e783a649a0d88e94d32a49af7c3ad61144a909d9 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sun, 21 May 2023 16:31:57 +0900 Subject: [PATCH 77/79] updated message on char edit error --- public/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/script.js b/public/script.js index 5b0b5cc35..2903328e6 100644 --- a/public/script.js +++ b/public/script.js @@ -5452,8 +5452,8 @@ $(document).ready(function () { error: function (jqXHR, exception) { $("#create_button").removeAttr("disabled"); $("#result_info").html("Error: no connection"); - console.log('Cant use that name! Invalid or already exists.'); - alert('Cant use that name! Invalid or already exists.'); + console.log('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.'); + alert('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.'); }, }); } From 0baacfbaed7e5605695965bb9deafaa280758fa5 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sun, 21 May 2023 17:35:29 +0900 Subject: [PATCH 78/79] debug console logs for AN show/hide --- public/script.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 2903328e6..da7dc865c 100644 --- a/public/script.js +++ b/public/script.js @@ -5676,10 +5676,13 @@ $(document).ready(function () { duration: 250, easing: animation_easing, }); + console.log('displayed AN panel'); + if ($("#ANBlockToggle") .siblings('.inline-drawer-content') .css('display') !== 'block') { $("#ANBlockToggle").click(); + console.log('opened AN box'); } } else { $("#floatingPrompt").transition({ @@ -5687,7 +5690,11 @@ $(document).ready(function () { duration: 250, easing: animation_easing, }); - setTimeout(function () { $("#floatingPrompt").hide(); }, 250); + setTimeout(function () { + $("#floatingPrompt").hide(); + console.log('hid AN panel'); + }, 250); + } } From 0f040eb4b0c0de466b2c5bc3ec23aca6101af9b3 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sun, 21 May 2023 17:49:30 +0900 Subject: [PATCH 79/79] fixed AN hide.show --- public/script.js | 53 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/public/script.js b/public/script.js index da7dc865c..1ff4bb145 100644 --- a/public/script.js +++ b/public/script.js @@ -5667,34 +5667,35 @@ $(document).ready(function () { var id = $(this).attr("id"); if (id == "option_toggle_AN") { - if (selected_group || this_chid !== undefined - && $("#floatingPrompt").css("display") !== 'flex') { - $("#floatingPrompt").css("display", "flex"); - $("#floatingPrompt").css("opacity", 0.0); - $("#floatingPrompt").transition({ - opacity: 1.0, - duration: 250, - easing: animation_easing, - }); - console.log('displayed AN panel'); + if (selected_group || this_chid) { + if ($("#floatingPrompt").css("display") !== 'flex') { + $("#floatingPrompt").css("display", "flex"); + $("#floatingPrompt").css("opacity", 0.0); + $("#floatingPrompt").transition({ + opacity: 1.0, + duration: 250, + easing: animation_easing, + }); + console.log('displayed AN panel'); + + if ($("#ANBlockToggle") + .siblings('.inline-drawer-content') + .css('display') !== 'block') { + $("#ANBlockToggle").click(); + console.log('opened AN box'); + } + } else { + $("#floatingPrompt").transition({ + opacity: 0.0, + duration: 250, + easing: animation_easing, + }); + setTimeout(function () { + $("#floatingPrompt").hide(); + console.log('hid AN panel'); + }, 250); - if ($("#ANBlockToggle") - .siblings('.inline-drawer-content') - .css('display') !== 'block') { - $("#ANBlockToggle").click(); - console.log('opened AN box'); } - } else { - $("#floatingPrompt").transition({ - opacity: 0.0, - duration: 250, - easing: animation_easing, - }); - setTimeout(function () { - $("#floatingPrompt").hide(); - console.log('hid AN panel'); - }, 250); - } }