From c3f988f246c80f80247941564f24ff787c6c3f00 Mon Sep 17 00:00:00 2001 From: Meus Artis <4709458+Meus-Artis@users.noreply.github.com> Date: Tue, 3 Dec 2024 01:09:41 -0500 Subject: [PATCH 01/29] Update users-public.js Better/more detailed console output for multi-user installs --- src/endpoints/users-public.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/endpoints/users-public.js b/src/endpoints/users-public.js index 5e6b60941..3d86fc619 100644 --- a/src/endpoints/users-public.js +++ b/src/endpoints/users-public.js @@ -67,17 +67,17 @@ router.post('/login', jsonParser, async (request, response) => { const user = await storage.getItem(toKey(request.body.handle)); if (!user) { - console.log('Login failed: User not found'); + console.log('Login failed: User', request.body.handle, 'not found'); return response.status(403).json({ error: 'Incorrect credentials' }); } if (!user.enabled) { - console.log('Login failed: User is disabled'); + console.log('Login failed: User', user.handle, 'is disabled'); return response.status(403).json({ error: 'User is disabled' }); } if (user.password && user.password !== getPasswordHash(request.body.password, user.salt)) { - console.log('Login failed: Incorrect password'); + console.log('Login failed: Incorrect password for', user.handle); return response.status(403).json({ error: 'Incorrect credentials' }); } @@ -88,7 +88,7 @@ router.post('/login', jsonParser, async (request, response) => { await loginLimiter.delete(ip); request.session.handle = user.handle; - console.log('Login successful:', user.handle, request.session); + console.log('Login successful:', user.handle, 'from', ip, 'at', request.session.touch); return response.json({ handle: user.handle }); } catch (error) { if (error instanceof RateLimiterRes) { @@ -115,12 +115,12 @@ router.post('/recover-step1', jsonParser, async (request, response) => { const user = await storage.getItem(toKey(request.body.handle)); if (!user) { - console.log('Recover step 1 failed: User not found'); + console.log('Recover step 1 failed: User', request.body.handle, 'not found'); return response.status(404).json({ error: 'User not found' }); } if (!user.enabled) { - console.log('Recover step 1 failed: User is disabled'); + console.log('Recover step 1 failed: User', user.handle, 'is disabled'); return response.status(403).json({ error: 'User is disabled' }); } @@ -153,12 +153,12 @@ router.post('/recover-step2', jsonParser, async (request, response) => { const ip = getIpFromRequest(request); if (!user) { - console.log('Recover step 2 failed: User not found'); + console.log('Recover step 2 failed: User', request.body.handle, 'not found'); return response.status(404).json({ error: 'User not found' }); } if (!user.enabled) { - console.log('Recover step 2 failed: User is disabled'); + console.log('Recover step 2 failed: User', user.handle, 'is disabled'); return response.status(403).json({ error: 'User is disabled' }); } From 4466da63bc27b0b7cb704e1bae978c9b208b1352 Mon Sep 17 00:00:00 2001 From: Meus Artis <4709458+Meus-Artis@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:56:40 -0500 Subject: [PATCH 02/29] Update users-public.js Replace session touch timestamp with Date() --- src/endpoints/users-public.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/endpoints/users-public.js b/src/endpoints/users-public.js index 3d86fc619..aa11199e0 100644 --- a/src/endpoints/users-public.js +++ b/src/endpoints/users-public.js @@ -88,7 +88,7 @@ router.post('/login', jsonParser, async (request, response) => { await loginLimiter.delete(ip); request.session.handle = user.handle; - console.log('Login successful:', user.handle, 'from', ip, 'at', request.session.touch); + console.log('Login successful:', user.handle, 'from', ip, 'at', Date().toLocaleString()); return response.json({ handle: user.handle }); } catch (error) { if (error instanceof RateLimiterRes) { From 41a3035a2ab31987ff2d76b3e97d20fa9d1aa1b6 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:22:53 +0000 Subject: [PATCH 03/29] Use filter order in group candidates list --- public/script.js | 4 ++-- public/scripts/group-chats.js | 11 ++++++----- public/scripts/power-user.js | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/public/script.js b/public/script.js index 5205a27cd..f803ac4f8 100644 --- a/public/script.js +++ b/public/script.js @@ -1637,7 +1637,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) { subEntities = entitiesFilter.applyFilters(subEntities, { clearScoreCache: false, tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false }); } if (doSort) { - sortEntitiesList(subEntities); + sortEntitiesList(subEntities, false); } entity.entities = subEntities; entity.hidden = subCount - subEntities.length; @@ -1665,7 +1665,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) { // Sort before returning if requested if (doSort) { - sortEntitiesList(entities); + sortEntitiesList(entities, false); } entitiesFilter.clearFuzzySearchCaches(); return entities; diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 0195b1d8d..0e106c3ea 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -1267,14 +1267,15 @@ function getGroupCharacters({ doFilter, onlyMembers } = {}) { .filter((x) => isGroupMember(thisGroup, x.avatar) == onlyMembers) .map((x, index) => ({ item: x, id: index, type: 'character' })); + if (doFilter) { + candidates = groupCandidatesFilter.applyFilters(candidates); + } + if (onlyMembers) { candidates.sort(sortMembersFn); } else { - sortEntitiesList(candidates); - } - - if (doFilter) { - candidates = groupCandidatesFilter.applyFilters(candidates); + const useFilterOrder = doFilter && !!$('#rm_group_filter').val(); + sortEntitiesList(candidates, useFilterOrder); } return candidates; diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js index 504d53b13..e27a90fbc 100644 --- a/public/scripts/power-user.js +++ b/public/scripts/power-user.js @@ -60,7 +60,6 @@ export { loadMovingUIState, collapseNewlines, playMessageSound, - sortEntitiesList, fixMarkdown, power_user, send_on_enter_options, @@ -2080,8 +2079,9 @@ const compareFunc = (first, second) => { /** * Sorts an array of entities based on the current sort settings * @param {any[]} entities An array of objects with an `item` property + * @param {boolean} forceSearch Whether to force search sorting */ -function sortEntitiesList(entities) { +export function sortEntitiesList(entities, forceSearch) { if (power_user.sort_field == undefined || entities.length === 0) { return; } @@ -2091,7 +2091,7 @@ function sortEntitiesList(entities) { return; } - const isSearch = $('#character_sort_order option[data-field="search"]').is(':selected'); + const isSearch = forceSearch || $('#character_sort_order option[data-field="search"]').is(':selected'); entities.sort((a, b) => { // Sort tags/folders will always be at the top From 3d8f8d90c3b57bff817445c5d679d677a8476974 Mon Sep 17 00:00:00 2001 From: IceFog72 <164350516+IceFog72@users.noreply.github.com> Date: Thu, 5 Dec 2024 03:23:11 +0200 Subject: [PATCH 04/29] Update stable-diffusion/style.css #sd_dropdown backdrop-filter fix --- public/scripts/extensions/stable-diffusion/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css index d4bff383d..ef9507cc2 100644 --- a/public/scripts/extensions/stable-diffusion/style.css +++ b/public/scripts/extensions/stable-diffusion/style.css @@ -4,7 +4,7 @@ #sd_dropdown { z-index: 30000; - backdrop-filter: blur(--SmartThemeBlurStrength); + backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); } #sd_comfy_open_workflow_editor { From 960db2d59bcf64bb2b1b0e980476333be539a920 Mon Sep 17 00:00:00 2001 From: IceFog72 <164350516+IceFog72@users.noreply.github.com> Date: Thu, 5 Dec 2024 03:25:13 +0200 Subject: [PATCH 05/29] Update tts/style.css .at-settings-separator padding fix --- public/scripts/extensions/tts/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions/tts/style.css b/public/scripts/extensions/tts/style.css index 960467c06..4d379a798 100644 --- a/public/scripts/extensions/tts/style.css +++ b/public/scripts/extensions/tts/style.css @@ -93,7 +93,7 @@ .at-settings-separator { margin-top: 10px; margin-bottom: 10px; - padding: 18x; + padding: 18px; font-weight: bold; border-top: 1px solid #e1e1e1; /* Grey line */ border-bottom: 1px solid #e1e1e1; /* Grey line */ From 373a0ad3211e30903668a49f7d49e6422200c59f Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Thu, 5 Dec 2024 12:59:03 +0000 Subject: [PATCH 06/29] Add config.yaml value for cards cache capacity. --- default/config.yaml | 2 ++ src/endpoints/characters.js | 7 ++++--- src/util.js | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/default/config.yaml b/default/config.yaml index 6f174e523..730ffa967 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -1,6 +1,8 @@ # -- DATA CONFIGURATION -- # Root directory for user data storage dataRoot: ./data +# The maximum amount of memory that parsed character cards can use in MB +cardsCacheCapacity: 100 # -- SERVER CONFIGURATION -- # Listen for incoming connections listen: false diff --git a/src/endpoints/characters.js b/src/endpoints/characters.js index b3be9d6f4..9c117cb31 100644 --- a/src/endpoints/characters.js +++ b/src/endpoints/characters.js @@ -14,7 +14,7 @@ import jimp from 'jimp'; import { AVATAR_WIDTH, AVATAR_HEIGHT } from '../constants.js'; import { jsonParser, urlencodedParser } from '../express-common.js'; -import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer, MemoryLimitedMap } from '../util.js'; +import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer, MemoryLimitedMap, getConfigValue } from '../util.js'; import { TavernCardValidator } from '../validator/TavernCardValidator.js'; import { parse, write } from '../character-card-parser.js'; import { readWorldInfoFile } from './worldinfo.js'; @@ -23,8 +23,9 @@ import { importRisuSprites } from './sprites.js'; const defaultAvatarPath = './public/img/ai4.png'; // KV-store for parsed character data -// 100 MB limit. Would take roughly 3000 characters to reach this limit -const characterDataCache = new MemoryLimitedMap(1024 * 1024 * 100); +const cacheCapacity = Number(getConfigValue('cardsCacheCapacity', 100)); // MB +// With 100 MB limit it would take roughly 3000 characters to reach this limit +const characterDataCache = new MemoryLimitedMap(1024 * 1024 * cacheCapacity); // Some Android devices require tighter memory management const isAndroid = process.platform === 'android'; diff --git a/src/util.js b/src/util.js index 623626d3d..7b8445453 100644 --- a/src/util.js +++ b/src/util.js @@ -680,8 +680,9 @@ export class MemoryLimitedMap { * @param {number} maxMemoryInBytes - The maximum allowed memory in bytes for string values. */ constructor(maxMemoryInBytes) { - if (typeof maxMemoryInBytes !== 'number' || maxMemoryInBytes <= 0) { - throw new Error('maxMemoryInBytes must be a positive number'); + if (typeof maxMemoryInBytes !== 'number' || maxMemoryInBytes <= 0 || isNaN(maxMemoryInBytes)) { + console.warn('Invalid maxMemoryInBytes, using a fallback value of 1 GB.'); + maxMemoryInBytes = 1024 * 1024 * 1024; // 1 GB } this.maxMemory = maxMemoryInBytes; this.currentMemory = 0; From 23a10fdc227954128ccf1da74ad723b92dcab752 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:32:30 +0000 Subject: [PATCH 07/29] Optimize past swipe counters performance --- public/index.html | 2 +- public/script.js | 11 +++++------ public/scripts/power-user.js | 4 ++-- public/style.css | 10 ++++++++++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index d8296c1fb..32723dd05 100644 --- a/public/index.html +++ b/public/index.html @@ -4183,7 +4183,7 @@