From ba6f7b7a98cf7a5eaf4f0e81da9779a9a668ced4 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:00:07 +0300 Subject: [PATCH 01/17] Fix QR editor sizing --- public/scripts/extensions/quick-reply/style.css | 1 + public/scripts/extensions/quick-reply/style.less | 1 + 2 files changed, 2 insertions(+) diff --git a/public/scripts/extensions/quick-reply/style.css b/public/scripts/extensions/quick-reply/style.css index ae6bb18c6..cb3129a59 100644 --- a/public/scripts/extensions/quick-reply/style.css +++ b/public/scripts/extensions/quick-reply/style.css @@ -350,6 +350,7 @@ } .popup:has(#qr--modalEditor) { aspect-ratio: unset; + width: unset; } .popup:has(#qr--modalEditor):has(.qr--isExecuting.qr--minimized) { min-width: unset; diff --git a/public/scripts/extensions/quick-reply/style.less b/public/scripts/extensions/quick-reply/style.less index 7261a514c..c5d2b2b70 100644 --- a/public/scripts/extensions/quick-reply/style.less +++ b/public/scripts/extensions/quick-reply/style.less @@ -415,6 +415,7 @@ .popup:has(#qr--modalEditor) { aspect-ratio: unset; + width: unset; &:has(.qr--isExecuting.qr--minimized) { min-width: unset; From b164084c0c9889c13958e221649171010137860f Mon Sep 17 00:00:00 2001 From: Joe Date: Mon, 21 Oct 2024 00:19:50 -0700 Subject: [PATCH 02/17] Enhancement: Make buttons scrollable --- public/scripts/slash-commands.js | 37 ++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index a34b4e544..6a4c5f63f 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -2074,7 +2074,32 @@ async function buttonsCallback(args, text) { let popup; const buttonContainer = document.createElement('div'); - buttonContainer.classList.add('flex-container', 'flexFlowColumn', 'wide100p', 'm-t-1'); + buttonContainer.classList.add('flex-container', 'flexFlowColumn', 'wide100p'); + + const scrollableContainer = document.createElement('div'); + scrollableContainer.style.maxHeight = '50vh'; // Use viewport height instead of fixed pixels + scrollableContainer.style.overflowY = 'auto'; + scrollableContainer.style.WebkitOverflowScrolling = 'touch'; // Enable momentum scrolling on iOS + scrollableContainer.classList.add('m-t-1', 'scrollable-buttons'); + + // Add custom CSS for better mobile scrolling + const style = document.createElement('style'); + style.textContent = ` + .scrollable-buttons { + -webkit-overflow-scrolling: touch; + overflow-y: auto; + flex-shrink: 1; + min-height: 0; + } + .scrollable-buttons::-webkit-scrollbar { + width: 6px; + } + .scrollable-buttons::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); + border-radius: 3px; + } + `; + document.head.appendChild(style); for (const [result, button] of resultToButtonMap) { const buttonElement = document.createElement('div'); @@ -2087,9 +2112,16 @@ async function buttonsCallback(args, text) { buttonContainer.appendChild(buttonElement); } + scrollableContainer.appendChild(buttonContainer); + const popupContainer = document.createElement('div'); popupContainer.innerHTML = safeValue; - popupContainer.appendChild(buttonContainer); + popupContainer.appendChild(scrollableContainer); + + // Ensure the popup uses flex layout + popupContainer.style.display = 'flex'; + popupContainer.style.flexDirection = 'column'; + popupContainer.style.maxHeight = '80vh'; // Limit the overall height of the popup popup = new Popup(popupContainer, POPUP_TYPE.TEXT, '', { okButton: 'Cancel' }); popup.show() @@ -4272,3 +4304,4 @@ sendTextarea.addEventListener('input', () => { sendTextarea.style.fontFamily = null; } }); + From 8f09aced83ab44088bb28ec81941136562fbfce2 Mon Sep 17 00:00:00 2001 From: Joe Date: Mon, 21 Oct 2024 00:57:15 -0700 Subject: [PATCH 03/17] Add scroll bar to make it obvious --- public/scripts/slash-commands.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 6a4c5f63f..08ea48536 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -2090,12 +2090,14 @@ async function buttonsCallback(args, text) { overflow-y: auto; flex-shrink: 1; min-height: 0; + scrollbar-width: thin; + scrollbar-color: rgba(255, 255, 255, 0.3) transparent; } .scrollable-buttons::-webkit-scrollbar { width: 6px; } .scrollable-buttons::-webkit-scrollbar-thumb { - background-color: rgba(0, 0, 0, 0.2); + background-color: rgba(255, 255, 255, 0.3); border-radius: 3px; } `; @@ -4304,4 +4306,3 @@ sendTextarea.addEventListener('input', () => { sendTextarea.style.fontFamily = null; } }); - From 030808d3081c4a2b296fab06ca79fa9942580c4a Mon Sep 17 00:00:00 2001 From: David Jimenez Date: Tue, 22 Oct 2024 19:05:51 +0100 Subject: [PATCH 04/17] feat: add Claude 3.5 Sonnet 20241022 API model --- public/index.html | 1 + public/scripts/extensions/caption/settings.html | 1 + 2 files changed, 2 insertions(+) diff --git a/public/index.html b/public/index.html index 5d5b0857b..6d9a6a3e5 100644 --- a/public/index.html +++ b/public/index.html @@ -2797,6 +2797,7 @@

Claude Model

+ diff --git a/public/scripts/extensions/caption/settings.html b/public/scripts/extensions/caption/settings.html index a388030b0..d9cfc7215 100644 --- a/public/scripts/extensions/caption/settings.html +++ b/public/scripts/extensions/caption/settings.html @@ -43,6 +43,7 @@ + From 2a60b6be0b12ad23c801c3c37803d3f0b79b2a0e Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:45:40 +0300 Subject: [PATCH 11/17] Bump package version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3ac436ef..9974db1ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sillytavern", - "version": "1.12.6", + "version": "1.12.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sillytavern", - "version": "1.12.6", + "version": "1.12.7", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 7bb9783fa..a94bc0a58 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "type": "git", "url": "https://github.com/SillyTavern/SillyTavern.git" }, - "version": "1.12.6", + "version": "1.12.7", "scripts": { "start": "node server.js", "start:no-csrf": "node server.js --disableCsrf", From d716bc0a07e606c6364ca5e7ef0656a737babf7e Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:39:37 +0300 Subject: [PATCH 12/17] Revert Google Translate client library --- package-lock.json | 7 +++++++ package.json | 1 + src/endpoints/translate.js | 41 +++++++++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9974db1ec..589401dad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "csrf-csrf": "^2.2.3", "express": "^4.21.0", "form-data": "^4.0.0", + "google-translate-api-browser": "^3.0.1", "google-translate-api-x": "^10.7.1", "helmet": "^7.1.0", "html-entities": "^2.5.2", @@ -3693,6 +3694,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/google-translate-api-browser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/google-translate-api-browser/-/google-translate-api-browser-3.0.1.tgz", + "integrity": "sha512-KTLodkyGBWMK9IW6QIeJ2zCuju4Z0CLpbkADKo+yLhbSTD4l+CXXpQ/xaynGVAzeBezzJG6qn8MLeqOq3SmW0A==", + "license": "MIT" + }, "node_modules/google-translate-api-x": { "version": "10.7.1", "resolved": "https://registry.npmjs.org/google-translate-api-x/-/google-translate-api-x-10.7.1.tgz", diff --git a/package.json b/package.json index a94bc0a58..3d8960053 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "csrf-csrf": "^2.2.3", "express": "^4.21.0", "form-data": "^4.0.0", + "google-translate-api-browser": "^3.0.1", "google-translate-api-x": "^10.7.1", "helmet": "^7.1.0", "html-entities": "^2.5.2", diff --git a/src/endpoints/translate.js b/src/endpoints/translate.js index 57387b63c..8a53e9de4 100644 --- a/src/endpoints/translate.js +++ b/src/endpoints/translate.js @@ -1,9 +1,10 @@ import https from 'node:https'; +import { createRequire } from 'node:module'; import fetch from 'node-fetch'; import express from 'express'; import bingTranslateApi from 'bing-translate-api'; -import googleTranslateApi from 'google-translate-api-x'; +import iconv from 'iconv-lite'; import { readSecret, SECRET_KEYS } from './secrets.js'; import { getConfigValue, uuidv4 } from '../util.js'; @@ -14,6 +15,30 @@ const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate'; export const router = express.Router(); +/** + * Get the Google Translate API client. + * @returns {import('google-translate-api-browser')} Google Translate API client + */ +function getGoogleTranslateClient() { + const require = createRequire(import.meta.url); + const googleTranslateApi = require('google-translate-api-browser'); + return googleTranslateApi; +} + +/** + * Tries to decode an ArrayBuffer to a string using iconv-lite for UTF-8. + * @param {ArrayBuffer} buffer ArrayBuffer + * @returns {string} Decoded string + */ +function decodeBuffer(buffer) { + try { + return iconv.decode(Buffer.from(buffer), 'utf-8'); + } catch (error) { + console.log('Failed to decode buffer:', error); + return Buffer.from(buffer).toString('utf-8'); + } +} + router.post('/libre', jsonParser, async (request, response) => { const key = readSecret(request.user.directories, SECRET_KEYS.LIBRE); const url = readSecret(request.user.directories, SECRET_KEYS.LIBRE_URL); @@ -81,8 +106,18 @@ router.post('/google', jsonParser, async (request, response) => { console.log('Input text: ' + text); - const result = await googleTranslateApi(text, { to: lang, forceBatch: false }); - const translatedText = Array.isArray(result) ? result.map(x => x.text).join('') : result.text; + const { generateRequestUrl, normaliseResponse } = getGoogleTranslateClient(); + const requestUrl = generateRequestUrl(text, { to: lang }); + const result = await fetch(requestUrl); + + if (!result.ok) { + console.log('Google Translate error: ', result.statusText); + return response.sendStatus(500); + } + + const buffer = await result.arrayBuffer(); + const translateResponse = normaliseResponse(JSON.parse(decodeBuffer(buffer))); + const translatedText = translateResponse.text; response.setHeader('Content-Type', 'text/plain; charset=utf-8'); console.log('Translated text: ' + translatedText); From 517b140911cb063c42790168c8510eab09fa6559 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:01:48 +0200 Subject: [PATCH 13/17] Localize only the moment instance --- public/scripts/i18n.js | 3 ++- public/scripts/utils.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/public/scripts/i18n.js b/public/scripts/i18n.js index 4764b1b8d..39dccda4d 100644 --- a/public/scripts/i18n.js +++ b/public/scripts/i18n.js @@ -9,6 +9,8 @@ var langs; // eslint-disable-next-line prefer-const var localeData; +export const getCurrentLocale = () => localeFile; + /** * An observer that will check if any new i18n elements are added to the document * @type {MutationObserver} @@ -215,7 +217,6 @@ function addLanguagesToDropdown() { } export async function initLocales() { - moment.locale(localeFile); langs = await fetch('/locales/lang.json').then(response => response.json()); localeData = await getLocaleData(localeFile); applyLocale(); diff --git a/public/scripts/utils.js b/public/scripts/utils.js index 1196f5c42..7bda1a499 100644 --- a/public/scripts/utils.js +++ b/public/scripts/utils.js @@ -7,6 +7,7 @@ import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js'; import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; import { getTagsList } from './tags.js'; import { groups, selected_group } from './group-chats.js'; +import { getCurrentLocale } from './i18n.js'; /** * Pagination status string template. @@ -831,7 +832,7 @@ export function timestampToMoment(timestamp) { } const iso8601 = parseTimestamp(timestamp); - const objMoment = iso8601 ? moment(iso8601) : moment.invalid(); + const objMoment = iso8601 ? moment(iso8601).locale(getCurrentLocale()) : moment.invalid(); dateCache.set(timestamp, objMoment); return objMoment; From 08d177e7ba5bcad5985d135ffe5aeabdee23bd11 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:31:15 +0000 Subject: [PATCH 14/17] Don't auto-swipe on aborted stream --- public/script.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/public/script.js b/public/script.js index 1bb05e4cc..9e6231541 100644 --- a/public/script.js +++ b/public/script.js @@ -3136,7 +3136,8 @@ class StreamingProcessor { //console.log("Generated text size:", text.length, text) - if (power_user.auto_swipe) { + const isAborted = this.abortController.signal.aborted; + if (power_user.auto_swipe && !isAborted) { function containsBlacklistedWords(str, blacklist, threshold) { const regex = new RegExp(`\\b(${blacklist.join('|')})\\b`, 'gi'); const matches = str.match(regex) || []; @@ -4583,7 +4584,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro playMessageSound(); } - if (power_user.auto_swipe) { + const isAborted = abortController && abortController.signal.aborted; + if (power_user.auto_swipe && !isAborted) { console.debug('checking for autoswipeblacklist on non-streaming message'); function containsBlacklistedWords(getMessage, blacklist, threshold) { console.debug('checking blacklisted words'); From 17b7f176765693b557dfe15be8cd7050cd24994f Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:14:35 +0200 Subject: [PATCH 15/17] Fix auto-continue with stream aborting Closes #3021 --- public/script.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/script.js b/public/script.js index 9e6231541..51e324dda 100644 --- a/public/script.js +++ b/public/script.js @@ -4770,6 +4770,11 @@ export function shouldAutoContinue(messageChunk, isImpersonate) { return false; } + if (abortController && abortController.signal.aborted) { + console.debug('Auto-continue is not triggered because the generation was stopped.'); + return false; + } + if (power_user.auto_continue.target_length <= 0) { console.log('Auto-continue target length is 0, not triggering auto-continue'); return false; From fb48d250419cfbf327cfd13c4609b35bce1e600c Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:41:59 +0200 Subject: [PATCH 16/17] Fix new character highlight --- public/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 51e324dda..507a0ca60 100644 --- a/public/script.js +++ b/public/script.js @@ -7185,7 +7185,7 @@ export function select_rm_info(type, charId, previousCharId = null) { importFlashTimeout = setTimeout(function () { if (type === 'char_import' || type === 'char_create') { // Find the page at which the character is located - const avatarFileName = `${charId}.png`; + const avatarFileName = charId; const charData = getEntitiesList({ doFilter: true }); const charIndex = charData.findIndex((x) => x?.item?.avatar?.startsWith(avatarFileName)); From a3ca407b2714df5af5a9f83aa925fd64fb778e24 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Wed, 6 Nov 2024 19:47:30 +0200 Subject: [PATCH 17/17] Backport llama.cpp-related DRY fixes from staging (#3051) * llama.cpp Enable dry w/ array convert The new PR that was merged needs an array instead of a str https://github.com/ggerganov/llama.cpp/pull/9702 * Safe sequence breakers parse * Support comma-separated list of llama.cpp sequence breakers #3026 --------- Co-authored-by: Beinsezii --- public/index.html | 3 +-- public/scripts/textgen-settings.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 0d6f1105b..2bba8e87b 100644 --- a/public/index.html +++ b/public/index.html @@ -1397,8 +1397,7 @@ - -