mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge remote-tracking branch 'upstream/staging' into quad-sample
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { fuzzySearchCharacters, fuzzySearchGroups, fuzzySearchTags, fuzzySearchWorldInfo, power_user } from './power-user.js';
|
||||
import { fuzzySearchCharacters, fuzzySearchGroups, fuzzySearchPersonas, fuzzySearchTags, fuzzySearchWorldInfo, power_user } from './power-user.js';
|
||||
import { tag_map } from './tags.js';
|
||||
|
||||
/**
|
||||
@@ -11,6 +11,7 @@ export const FILTER_TYPES = {
|
||||
FAV: 'fav',
|
||||
GROUP: 'group',
|
||||
WORLD_INFO_SEARCH: 'world_info_search',
|
||||
PERSONA_SEARCH: 'persona_search',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -39,6 +40,7 @@ export class FilterHelper {
|
||||
[FILTER_TYPES.FAV]: this.favFilter.bind(this),
|
||||
[FILTER_TYPES.TAG]: this.tagFilter.bind(this),
|
||||
[FILTER_TYPES.WORLD_INFO_SEARCH]: this.wiSearchFilter.bind(this),
|
||||
[FILTER_TYPES.PERSONA_SEARCH]: this.personaSearchFilter.bind(this),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -51,6 +53,7 @@ export class FilterHelper {
|
||||
[FILTER_TYPES.FAV]: false,
|
||||
[FILTER_TYPES.TAG]: { excluded: [], selected: [] },
|
||||
[FILTER_TYPES.WORLD_INFO_SEARCH]: '',
|
||||
[FILTER_TYPES.PERSONA_SEARCH]: '',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,6 +72,22 @@ export class FilterHelper {
|
||||
return data.filter(entity => fuzzySearchResults.includes(entity.uid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a search filter to Persona data.
|
||||
* @param {string[]} data The data to filter.
|
||||
* @returns {string[]} The filtered data.
|
||||
*/
|
||||
personaSearchFilter(data) {
|
||||
const term = this.filterData[FILTER_TYPES.PERSONA_SEARCH];
|
||||
|
||||
if (!term) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const fuzzySearchResults = fuzzySearchPersonas(data, term);
|
||||
return data.filter(entity => fuzzySearchResults.includes(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given entity is tagged with the given tag ID.
|
||||
* @param {object} entity Searchable entity
|
||||
|
@@ -108,6 +108,7 @@ export const group_activation_strategy = {
|
||||
export const group_generation_mode = {
|
||||
SWAP: 0,
|
||||
APPEND: 1,
|
||||
APPEND_DISABLED: 2,
|
||||
};
|
||||
|
||||
const DEFAULT_AUTO_MODE_DELAY = 5;
|
||||
@@ -325,7 +326,7 @@ export function getGroupDepthPrompts(groupId, characterId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines group members info a single string. Only for groups with generation mode set to APPEND.
|
||||
* Combines group members cards into a single string. Only for groups with generation mode set to APPEND or APPEND_DISABLED.
|
||||
* @param {string} groupId Group ID
|
||||
* @param {number} characterId Current Character ID
|
||||
* @returns {{description: string, personality: string, scenario: string, mesExamples: string}} Group character cards combined
|
||||
@@ -334,7 +335,7 @@ export function getGroupCharacterCards(groupId, characterId) {
|
||||
console.debug('getGroupCharacterCards entered for group: ', groupId);
|
||||
const group = groups.find(x => x.id === groupId);
|
||||
|
||||
if (!group || group?.generation_mode !== group_generation_mode.APPEND || !Array.isArray(group.members) || !group.members.length) {
|
||||
if (!group || !group?.generation_mode || !Array.isArray(group.members) || !group.members.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -354,7 +355,7 @@ export function getGroupCharacterCards(groupId, characterId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (group.disabled_members.includes(member) && characterId !== index) {
|
||||
if (group.disabled_members.includes(member) && characterId !== index && group.generation_mode !== group_generation_mode.APPEND_DISABLED) {
|
||||
console.debug(`Skipping disabled group member: ${member}`);
|
||||
continue;
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import {
|
||||
name1,
|
||||
saveMetadata,
|
||||
saveSettingsDebounced,
|
||||
setUserAvatar,
|
||||
setUserName,
|
||||
this_chid,
|
||||
user_avatar,
|
||||
@@ -187,7 +188,7 @@ export function autoSelectPersona(name) {
|
||||
for (const [key, value] of Object.entries(power_user.personas)) {
|
||||
if (value === name) {
|
||||
console.log(`Auto-selecting persona ${key} for name ${name}`);
|
||||
$(`.avatar[imgfile="${key}"]`).trigger('click');
|
||||
setUserAvatar(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -209,7 +210,8 @@ export async function updatePersonaNameIfExists(avatarId, newName) {
|
||||
}
|
||||
}
|
||||
|
||||
async function bindUserNameToPersona() {
|
||||
async function bindUserNameToPersona(e) {
|
||||
e?.stopPropagation();
|
||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||
|
||||
if (!avatarId) {
|
||||
@@ -331,7 +333,8 @@ async function lockUserNameToChat() {
|
||||
updateUserLockIcon();
|
||||
}
|
||||
|
||||
async function deleteUserAvatar() {
|
||||
async function deleteUserAvatar(e) {
|
||||
e?.stopPropagation();
|
||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||
|
||||
if (!avatarId) {
|
||||
@@ -400,6 +403,9 @@ function onPersonaDescriptionInput() {
|
||||
object.description = power_user.persona_description;
|
||||
}
|
||||
|
||||
$(`.avatar-container[imgfile="${user_avatar}"] .ch_description`)
|
||||
.text(power_user.persona_description || '[No description]')
|
||||
.toggleClass('text_muted', !power_user.persona_description);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
@@ -425,7 +431,8 @@ function onPersonaDescriptionPositionInput() {
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
async function setDefaultPersona() {
|
||||
async function setDefaultPersona(e) {
|
||||
e?.stopPropagation();
|
||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||
|
||||
if (!avatarId) {
|
||||
@@ -481,7 +488,7 @@ function updateUserLockIcon() {
|
||||
$('#lock_user_name').toggleClass('fa-lock', hasLock);
|
||||
}
|
||||
|
||||
function setChatLockedPersona() {
|
||||
async function setChatLockedPersona() {
|
||||
// Define a persona for this chat
|
||||
let chatPersona = '';
|
||||
|
||||
@@ -502,10 +509,10 @@ function setChatLockedPersona() {
|
||||
}
|
||||
|
||||
// Find the avatar file
|
||||
const personaAvatar = $(`.avatar[imgfile="${chatPersona}"]`).trigger('click');
|
||||
const userAvatars = await getUserAvatars(false);
|
||||
|
||||
// Avatar missing (persona deleted)
|
||||
if (chat_metadata['persona'] && personaAvatar.length == 0) {
|
||||
if (chat_metadata['persona'] && !userAvatars.includes(chatPersona)) {
|
||||
console.warn('Persona avatar not found, unlocking persona');
|
||||
delete chat_metadata['persona'];
|
||||
updateUserLockIcon();
|
||||
@@ -513,7 +520,7 @@ function setChatLockedPersona() {
|
||||
}
|
||||
|
||||
// Default persona missing
|
||||
if (power_user.default_persona && personaAvatar.length == 0) {
|
||||
if (power_user.default_persona && !userAvatars.includes(power_user.default_persona)) {
|
||||
console.warn('Default persona avatar not found, clearing default persona');
|
||||
power_user.default_persona = null;
|
||||
saveSettingsDebounced();
|
||||
@@ -521,7 +528,7 @@ function setChatLockedPersona() {
|
||||
}
|
||||
|
||||
// Persona avatar found, select it
|
||||
personaAvatar.trigger('click');
|
||||
setUserAvatar(chatPersona);
|
||||
updateUserLockIcon();
|
||||
}
|
||||
|
||||
@@ -560,7 +567,7 @@ async function onPersonasRestoreInput(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
const avatarsList = await getUserAvatars();
|
||||
const avatarsList = await getUserAvatars(false);
|
||||
const warnings = [];
|
||||
|
||||
// Merge personas with existing ones
|
||||
|
@@ -1831,6 +1831,23 @@ export function fuzzySearchWorldInfo(data, searchValue) {
|
||||
return results.map(x => x.item?.uid);
|
||||
}
|
||||
|
||||
export function fuzzySearchPersonas(data, searchValue) {
|
||||
data = data.map(x => ({ key: x, description: power_user.persona_descriptions[x]?.description ?? '', name: power_user.personas[x] ?? '' }));
|
||||
const fuse = new Fuse(data, {
|
||||
keys: [
|
||||
{ name: 'name', weight: 4 },
|
||||
{ name: 'description', weight: 1 },
|
||||
],
|
||||
includeScore: true,
|
||||
ignoreLocation: true,
|
||||
threshold: 0.2,
|
||||
});
|
||||
|
||||
const results = fuse.search(searchValue);
|
||||
console.debug('Personas fuzzy search results for ' + searchValue, results);
|
||||
return results.map(x => x.item?.key);
|
||||
}
|
||||
|
||||
export function fuzzySearchTags(searchValue) {
|
||||
const fuse = new Fuse(tags, {
|
||||
keys: [
|
||||
|
Reference in New Issue
Block a user