Merge branch 'staging' into enable-autoselect-inputs

This commit is contained in:
Wolfsblvt
2024-08-18 03:37:36 +02:00
149 changed files with 9512 additions and 2143 deletions

View File

@@ -156,6 +156,7 @@ import {
ensureImageFormatSupported,
flashHighlight,
isTrueBoolean,
toggleDrawer,
} from './scripts/utils.js';
import { debounce_timeout } from './scripts/constants.js';
@@ -224,10 +225,10 @@ import {
import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_settings } from './scripts/backgrounds.js';
import { hideLoader, showLoader } from './scripts/loader.js';
import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels } from './scripts/textgen-models.js';
import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels } from './scripts/textgen-models.js';
import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId } from './scripts/chats.js';
import { initPresetManager } from './scripts/preset-manager.js';
import { MacrosParser, evaluateMacros } from './scripts/macros.js';
import { MacrosParser, evaluateMacros, getLastMessageId } from './scripts/macros.js';
import { currentUser, setUserControls } from './scripts/user.js';
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
@@ -424,6 +425,8 @@ export const event_types = {
CHATCOMPLETION_MODEL_CHANGED: 'chatcompletion_model_changed',
OAI_PRESET_CHANGED_BEFORE: 'oai_preset_changed_before',
OAI_PRESET_CHANGED_AFTER: 'oai_preset_changed_after',
OAI_PRESET_EXPORT_READY: 'oai_preset_export_ready',
OAI_PRESET_IMPORT_READY: 'oai_preset_import_ready',
WORLDINFO_SETTINGS_UPDATED: 'worldinfo_settings_updated',
WORLDINFO_UPDATED: 'worldinfo_updated',
CHARACTER_EDITED: 'character_edited',
@@ -439,6 +442,7 @@ export const event_types = {
GROUP_CHAT_CREATED: 'group_chat_created',
GENERATE_BEFORE_COMBINE_PROMPTS: 'generate_before_combine_prompts',
GENERATE_AFTER_COMBINE_PROMPTS: 'generate_after_combine_prompts',
GENERATE_AFTER_DATA: 'generate_after_data',
GROUP_MEMBER_DRAFTED: 'group_member_drafted',
WORLD_INFO_ACTIVATED: 'world_info_activated',
TEXT_COMPLETION_SETTINGS_READY: 'text_completion_settings_ready',
@@ -455,6 +459,7 @@ export const event_types = {
LLM_FUNCTION_TOOL_REGISTER: 'llm_function_tool_register',
LLM_FUNCTION_TOOL_CALL: 'llm_function_tool_call',
ONLINE_STATUS_CHANGED: 'online_status_changed',
IMAGE_SWIPED: 'image_swiped',
};
export const eventSource = new EventEmitter();
@@ -570,6 +575,7 @@ export const system_message_types = {
* @enum {number} Extension prompt types
*/
export const extension_prompt_types = {
NONE: -1,
IN_PROMPT: 0,
IN_CHAT: 1,
BEFORE_PROMPT: 2,
@@ -909,6 +915,7 @@ async function firstLoadInit() {
await readSecretState();
initLocales();
initDefaultSlashCommands();
initTextGenModels();
await getSystemMessages();
sendSystemMessage(system_message_types.WELCOME);
await getSettings();
@@ -929,10 +936,17 @@ async function firstLoadInit() {
initCfg();
initLogprobs();
doDailyExtensionUpdatesCheck();
hideLoader();
await hideLoader();
await fixViewport();
await eventSource.emit(event_types.APP_READY);
}
async function fixViewport() {
document.body.style.position = 'absolute';
await delay(1);
document.body.style.position = '';
}
function cancelStatusCheck() {
abortStatusCheck?.abort();
abortStatusCheck = new AbortController();
@@ -1712,16 +1726,24 @@ export async function replaceCurrentChat() {
}
export function showMoreMessages() {
let messageId = Number($('#chat').children('.mes').first().attr('mesid'));
const firstDisplayedMesId = $('#chat').children('.mes').first().attr('mesid');
let messageId = Number(firstDisplayedMesId);
let count = power_user.chat_truncation || Number.MAX_SAFE_INTEGER;
// If there are no messages displayed, or the message somehow has no mesid, we default to one higher than last message id,
// so the first "new" message being shown will be the last available message
if (isNaN(messageId)) {
messageId = getLastMessageId() + 1;
}
console.debug('Inserting messages before', messageId, 'count', count, 'chat length', chat.length);
const prevHeight = $('#chat').prop('scrollHeight');
while (messageId > 0 && count > 0) {
let newMessageId = messageId - 1;
addOneMessage(chat[newMessageId], { insertBefore: messageId >= chat.length ? null : messageId, scroll: false, forceId: newMessageId });
count--;
messageId--;
addOneMessage(chat[messageId], { insertBefore: messageId + 1, scroll: false, forceId: messageId });
}
if (messageId == 0) {
@@ -2091,6 +2113,7 @@ export function updateMessageBlock(messageId, message) {
export function appendMediaToMessage(mes, messageElement, adjustScroll = true) {
// Add image to message
if (mes.extra?.image) {
const container = messageElement.find('.mes_img_container');
const chatHeight = $('#chat').prop('scrollHeight');
const image = messageElement.find('.mes_img');
const text = messageElement.find('.mes_text');
@@ -2106,9 +2129,27 @@ export function appendMediaToMessage(mes, messageElement, adjustScroll = true) {
});
image.attr('src', mes.extra?.image);
image.attr('title', mes.extra?.title || mes.title || '');
messageElement.find('.mes_img_container').addClass('img_extra');
container.addClass('img_extra');
image.toggleClass('img_inline', isInline);
text.toggleClass('displayNone', !isInline);
const imageSwipes = mes.extra.image_swipes;
if (Array.isArray(imageSwipes) && imageSwipes.length > 0) {
container.addClass('img_swipes');
const counter = container.find('.mes_img_swipe_counter');
const currentImage = imageSwipes.indexOf(mes.extra.image) + 1;
counter.text(`${currentImage}/${imageSwipes.length}`);
const swipeLeft = container.find('.mes_img_swipe_left');
swipeLeft.off('click').on('click', function () {
eventSource.emit(event_types.IMAGE_SWIPED, { message: mes, element: messageElement, direction: 'left' });
});
const swipeRight = container.find('.mes_img_swipe_right');
swipeRight.off('click').on('click', function () {
eventSource.emit(event_types.IMAGE_SWIPED, { message: mes, element: messageElement, direction: 'right' });
});
}
}
// Add file to message
@@ -2462,26 +2503,30 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re
* @returns {string[]} Array of stopping strings
*/
export function getStoppingStrings(isImpersonate, isContinue) {
const charString = `\n${name2}:`;
const userString = `\n${name1}:`;
const result = isImpersonate ? [charString] : [userString];
const result = [];
result.push(userString);
if (power_user.context.names_as_stop_strings) {
const charString = `\n${name2}:`;
const userString = `\n${name1}:`;
result.push(isImpersonate ? charString : userString);
if (isContinue && Array.isArray(chat) && chat[chat.length - 1]?.is_user) {
result.push(charString);
}
result.push(userString);
// Add other group members as the stopping strings
if (selected_group) {
const group = groups.find(x => x.id === selected_group);
if (isContinue && Array.isArray(chat) && chat[chat.length - 1]?.is_user) {
result.push(charString);
}
if (group && Array.isArray(group.members)) {
const names = group.members
.map(x => characters.find(y => y.avatar == x))
.filter(x => x && x.name && x.name !== name2)
.map(x => `\n${x.name}:`);
result.push(...names);
// Add group members as stopping strings if generating for a specific group member or user. (Allow slash commands to work around name stopping string restrictions)
if (selected_group && (name2 || isImpersonate)) {
const group = groups.find(x => x.id === selected_group);
if (group && Array.isArray(group.members)) {
const names = group.members
.map(x => characters.find(y => y.avatar == x))
.filter(x => x && x.name && x.name !== name2)
.map(x => `\n${x.name}:`);
result.push(...names);
}
}
}
@@ -2800,6 +2845,8 @@ class StreamingProcessor {
this.messageDom = null;
this.messageTextDom = null;
this.messageTimerDom = null;
this.messageTokenCounterDom = null;
/** @type {HTMLTextAreaElement} */
this.sendTextarea = document.querySelector('#send_textarea');
this.type = type;
this.force_name2 = force_name2;
@@ -2815,6 +2862,15 @@ class StreamingProcessor {
this.messageLogprobs = [];
}
#checkDomElements(messageId) {
if (this.messageDom === null || this.messageTextDom === null) {
this.messageDom = document.querySelector(`#chat .mes[mesid="${messageId}"]`);
this.messageTextDom = this.messageDom?.querySelector('.mes_text');
this.messageTimerDom = this.messageDom?.querySelector('.mes_timer');
this.messageTokenCounterDom = this.messageDom?.querySelector('.tokenCounterDisplay');
}
}
showMessageButtons(messageId) {
if (messageId == -1) {
return;
@@ -2843,9 +2899,7 @@ class StreamingProcessor {
else {
await saveReply(this.type, text, true);
messageId = chat.length - 1;
this.messageDom = document.querySelector(`#chat .mes[mesid="${messageId}"]`);
this.messageTextDom = this.messageDom.querySelector('.mes_text');
this.messageTimerDom = this.messageDom.querySelector('.mes_timer');
this.#checkDomElements(messageId);
this.showMessageButtons(messageId);
}
@@ -2881,9 +2935,10 @@ class StreamingProcessor {
this.sendTextarea.dispatchEvent(new Event('input', { bubbles: true }));
}
else {
let currentTime = new Date();
this.#checkDomElements(messageId);
const currentTime = new Date();
// Don't waste time calculating token count for streaming
let currentTokenCount = isFinal && power_user.message_token_count_enabled ? getTokenCount(processedText, 0) : 0;
const currentTokenCount = isFinal && power_user.message_token_count_enabled ? getTokenCount(processedText, 0) : 0;
const timePassed = formatGenerationTimer(this.timeStarted, currentTime, currentTokenCount);
chat[messageId]['mes'] = processedText;
chat[messageId]['gen_started'] = this.timeStarted;
@@ -2895,8 +2950,9 @@ class StreamingProcessor {
}
chat[messageId]['extra']['token_count'] = currentTokenCount;
const tokenCounter = $(`#chat .mes[mesid="${messageId}"] .tokenCounterDisplay`);
tokenCounter.text(`${currentTokenCount}t`);
if (this.messageTokenCounterDom instanceof HTMLElement) {
this.messageTokenCounterDom.textContent = `${currentTokenCount}t`;
}
}
if ((this.type == 'swipe' || this.type === 'continue') && Array.isArray(chat[messageId]['swipes'])) {
@@ -2904,16 +2960,20 @@ class StreamingProcessor {
chat[messageId]['swipe_info'][chat[messageId]['swipe_id']] = { 'send_date': chat[messageId]['send_date'], 'gen_started': chat[messageId]['gen_started'], 'gen_finished': chat[messageId]['gen_finished'], 'extra': JSON.parse(JSON.stringify(chat[messageId]['extra'])) };
}
let formattedText = messageFormatting(
const formattedText = messageFormatting(
processedText,
chat[messageId].name,
chat[messageId].is_system,
chat[messageId].is_user,
messageId,
);
this.messageTextDom.innerHTML = formattedText;
this.messageTimerDom.textContent = timePassed.timerValue;
this.messageTimerDom.title = timePassed.timerTitle;
if (this.messageTextDom instanceof HTMLElement) {
this.messageTextDom.innerHTML = formattedText;
}
if (this.messageTimerDom instanceof HTMLElement) {
this.messageTimerDom.textContent = timePassed.timerValue;
this.messageTimerDom.title = timePassed.timerTitle;
}
this.setFirstSwipe(messageId);
}
@@ -3199,6 +3259,23 @@ function restoreResponseLength(api, responseLength) {
}
}
/**
* Removes last message from the chat DOM.
* @returns {Promise<void>} Resolves when the message is removed.
*/
function removeLastMessage() {
return new Promise((resolve) => {
const lastMes = $('#chat').children('.mes').last();
if (lastMes.length === 0) {
return resolve();
}
lastMes.hide(animation_duration, function () {
$(this).remove();
resolve();
});
});
}
/**
* Runs a generation using the current chat context.
* @param {string} type Generation type
@@ -3331,9 +3408,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
}
else if (type !== 'quiet' && type !== 'swipe' && !isImpersonate && !dryRun && chat.length) {
chat.length = chat.length - 1;
$('#chat').children().last().hide(250, function () {
$(this).remove();
});
await removeLastMessage();
await eventSource.emit(event_types.MESSAGE_DELETED, chat.length);
}
}
@@ -3581,6 +3656,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
let chat2 = [];
let continue_mag = '';
const userMessageIndices = [];
const lastUserMessageIndex = coreChat.findLastIndex(x => x.is_user);
for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) {
if (main_api == 'openai') {
@@ -3599,6 +3675,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.FIRST);
}
if (lastUserMessageIndex >= 0 && j === lastUserMessageIndex && isInstruct) {
// Reformat with the last input sequence (if any)
chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.LAST);
}
// Do not suffix the message for continuation
if (i === 0 && isContinue) {
if (isInstruct) {
@@ -3624,7 +3705,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
mes: power_user.instruct.user_alignment_message,
is_user: true,
};
userAlignmentMessage = formatMessageHistoryItem(alignmentMessage, isInstruct, false);
userAlignmentMessage = formatMessageHistoryItem(alignmentMessage, isInstruct, force_output_sequence.FIRST);
}
// Call combined AN into Generate
@@ -3886,7 +3967,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
// Get instruct mode line
if (isInstruct && !isContinue) {
const name = (quiet_prompt && !quietToLoud) ? (quietName ?? 'System') : (isImpersonate ? name1 : name2);
const name = (quiet_prompt && !quietToLoud && !isImpersonate) ? (quietName ?? 'System') : (isImpersonate ? name1 : name2);
const isQuiet = quiet_prompt && type == 'quiet';
lastMesString += formatInstructModePrompt(name, isImpersonate, promptBias, name1, name2, isQuiet, quietToLoud);
}
@@ -4167,6 +4248,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
}
}
await eventSource.emit(event_types.GENERATE_AFTER_DATA, generate_data);
if (dryRun) {
generatedPromptCache = '';
return Promise.resolve();
@@ -4698,6 +4781,7 @@ export async function sendMessageAsUser(messageText, messageBias, insertAt = nul
await eventSource.emit(event_types.MESSAGE_SENT, chat_id);
addOneMessage(message);
await eventSource.emit(event_types.USER_MESSAGE_RENDERED, chat_id);
await saveChatConditional();
}
}
@@ -5029,7 +5113,7 @@ function setInContextMessages(lastmsg, type) {
* @param {object} data Generation data
* @returns {Promise<object>} Response data from the API
*/
async function sendGenerationRequest(type, data) {
export async function sendGenerationRequest(type, data) {
if (main_api === 'openai') {
return await sendOpenAIRequest(type, data.prompt, abortController.signal);
}
@@ -5061,7 +5145,7 @@ async function sendGenerationRequest(type, data) {
* @param {object} data Generation data
* @returns {Promise<any>} Streaming generator
*/
async function sendStreamingRequest(type, data) {
export async function sendStreamingRequest(type, data) {
if (abortController?.signal?.aborted) {
throw new Error('Generation was aborted.');
}
@@ -5342,9 +5426,11 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
getMessage = fixMarkdown(getMessage, false);
}
const nameToTrim2 = isImpersonate ? name1 : name2;
const nameToTrim2 = isImpersonate
? (!power_user.allow_name1_display ? name1 : '')
: (!power_user.allow_name2_display ? name2 : '');
if (getMessage.startsWith(nameToTrim2 + ':')) {
if (nameToTrim2 && getMessage.startsWith(nameToTrim2 + ':')) {
getMessage = getMessage.replace(nameToTrim2 + ':', '');
getMessage = getMessage.trimStart();
}
@@ -5565,6 +5651,7 @@ export function activateSendButtons() {
is_send_press = false;
$('#send_but').removeClass('displayNone');
$('#mes_continue').removeClass('displayNone');
$('#mes_impersonate').removeClass('displayNone');
$('.mes_buttons:last').show();
hideStopButton();
}
@@ -5572,6 +5659,7 @@ export function activateSendButtons() {
export function deactivateSendButtons() {
$('#send_but').addClass('displayNone');
$('#mes_continue').addClass('displayNone');
$('#mes_impersonate').addClass('displayNone');
showStopButton();
}
@@ -6022,9 +6110,10 @@ async function getChatResult() {
const message = getFirstMessage();
if (message.mes) {
chat.push(message);
await saveChatConditional();
freshChat = true;
}
// Make sure the chat appears on the server
await saveChatConditional();
}
await loadItemizedPrompts(getCurrentChatId());
await printMessages();
@@ -6076,7 +6165,7 @@ export async function openCharacterChat(file_name) {
chat_metadata = {};
await getChat();
$('#selected_chat_pole').val(file_name);
await createOrEditCharacter();
await createOrEditCharacter(new CustomEvent('newChat'));
}
////////// OPTIMZED MAIN API CHANGE FUNCTION ////////////
@@ -6361,7 +6450,7 @@ export async function getSettings() {
loadHordeSettings(settings);
// Load power user settings
loadPowerUserSettings(settings, data);
await loadPowerUserSettings(settings, data);
// Load character tags
loadTagsSettings(settings);
@@ -6778,6 +6867,11 @@ export async function displayPastChats() {
const fileName = chat['file_name'];
const chatContent = rawChats[fileName];
// Make sure empty chats are displayed when there is no search query
if (Array.isArray(chatContent) && !chatContent.length && !searchQuery) {
return true;
}
// // Uncomment this to return to old behavior (classical full-substring search).
// return chatContent && Object.values(chatContent).some(message => message?.mes?.toLowerCase()?.includes(searchQuery.toLowerCase()));
@@ -7866,6 +7960,8 @@ window['SillyTavern'].getContext = function () {
eventTypes: event_types,
addOneMessage: addOneMessage,
generate: Generate,
sendStreamingRequest: sendStreamingRequest,
sendGenerationRequest: sendGenerationRequest,
stopGeneration: stopGeneration,
getTokenCount: getTokenCount,
extensionPrompts: extension_prompts,
@@ -8259,6 +8355,7 @@ const swipe_right = () => {
};
const CONNECT_API_MAP = {
// Default APIs not contined inside text gen / chat gen
'kobold': {
selected: 'kobold',
button: '#api_button',
@@ -8270,147 +8367,48 @@ const CONNECT_API_MAP = {
selected: 'novel',
button: '#api_button_novel',
},
'ooba': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.OOBA,
},
'tabby': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.TABBY,
},
'llamacpp': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.LLAMACPP,
},
'ollama': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.OLLAMA,
},
'mancer': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.MANCER,
},
'vllm': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.VLLM,
},
'aphrodite': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.APHRODITE,
},
'koboldcpp': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.KOBOLDCPP,
},
// KoboldCpp alias
'kcpp': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.KOBOLDCPP,
},
'togetherai': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.TOGETHERAI,
},
'openai': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.OPENAI,
},
// OpenAI alias
'oai': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.OPENAI,
},
'claude': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.CLAUDE,
},
'windowai': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.WINDOWAI,
},
// OpenRouter special naming, to differentiate between chat comp and text comp
'openrouter': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.OPENROUTER,
},
'scale': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.SCALE,
},
'ai21': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.AI21,
},
'makersuite': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.MAKERSUITE,
},
'mistralai': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.MISTRALAI,
},
'custom': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.CUSTOM,
},
'cohere': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.COHERE,
},
'perplexity': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.PERPLEXITY,
},
'groq': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.GROQ,
},
'01ai': {
selected: 'openai',
button: '#api_button_openai',
source: chat_completion_sources.ZEROONEAI,
},
'infermaticai': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.INFERMATICAI,
},
'dreamgen': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.DREAMGEN,
},
'openrouter-text': {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.OPENROUTER,
},
'huggingface': {
};
// Fill connections map from textgen_types and chat_completion_sources
for (const textGenType of Object.values(textgen_types)) {
if (CONNECT_API_MAP[textGenType]) continue;
CONNECT_API_MAP[textGenType] = {
selected: 'textgenerationwebui',
button: '#api_button_textgenerationwebui',
type: textgen_types.HUGGINGFACE,
},
};
type: textGenType,
};
}
for (const chatCompletionSource of Object.values(chat_completion_sources)) {
if (CONNECT_API_MAP[chatCompletionSource]) continue;
CONNECT_API_MAP[chatCompletionSource] = {
selected: 'openai',
button: '#api_button_openai',
source: chatCompletionSource,
};
}
async function selectContextCallback(_, name) {
if (!name) {
@@ -8543,7 +8541,7 @@ export async function processDroppedFiles(files, data = new Map()) {
for (const file of files) {
const extension = file.name.split('.').pop().toLowerCase();
if (allowedMimeTypes.includes(file.type) || allowedExtensions.includes(extension)) {
if (allowedMimeTypes.some(x => file.type.startsWith(x)) || allowedExtensions.includes(extension)) {
const preservedName = data instanceof Map && data.get(file);
await importCharacter(file, preservedName);
} else {
@@ -9142,14 +9140,14 @@ jQuery(async function () {
$('#send_textarea').on('focusin focus click', () => {
S_TAPreviouslyFocused = true;
});
$('#send_but, #option_regenerate, #option_continue, #mes_continue').on('click', () => {
$('#send_but, #option_regenerate, #option_continue, #mes_continue, #mes_impersonate').on('click', () => {
if (S_TAPreviouslyFocused) {
$('#send_textarea').focus();
}
});
$(document).click(event => {
if ($(':focus').attr('id') !== 'send_textarea') {
var validIDs = ['options_button', 'send_but', 'mes_continue', 'send_textarea', 'option_regenerate', 'option_continue'];
var validIDs = ['options_button', 'send_but', 'mes_impersonate', 'mes_continue', 'send_textarea', 'option_regenerate', 'option_continue'];
if (!validIDs.includes($(event.target).attr('id'))) {
S_TAPreviouslyFocused = false;
}
@@ -9185,6 +9183,9 @@ jQuery(async function () {
debouncedCharacterSearch(searchQuery);
});
$('#mes_impersonate').on('click', function () {
$('#option_impersonate').trigger('click');
});
$('#mes_continue').on('click', function () {
$('#option_continue').trigger('click');
@@ -9806,8 +9807,8 @@ jQuery(async function () {
hideMenu();
});
$('#newChatFromManageScreenButton').on('click', function () {
doNewChat({ deleteCurrentChat: false });
$('#newChatFromManageScreenButton').on('click', async function () {
await doNewChat({ deleteCurrentChat: false });
$('#select_chat_cross').trigger('click');
});
@@ -10482,8 +10483,9 @@ jQuery(async function () {
}
// Set the height of "autoSetHeight" textareas within the drawer to their scroll height
$(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(function () {
resetScrollHeight($(this));
$(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () {
await resetScrollHeight($(this));
return;
});
} else if (drawerWasOpenAlready) { //to close manually
@@ -10556,8 +10558,9 @@ jQuery(async function () {
$(this).closest('.inline-drawer').find('.inline-drawer-content').stop().slideToggle();
// Set the height of "autoSetHeight" textareas within the inline-drawer to their scroll height
$(this).closest('.inline-drawer').find('.inline-drawer-content textarea.autoSetHeight').each(function () {
resetScrollHeight($(this));
$(this).closest('.inline-drawer').find('.inline-drawer-content textarea.autoSetHeight').each(async function () {
await resetScrollHeight($(this));
return;
});
});
@@ -10638,12 +10641,19 @@ jQuery(async function () {
}
});
$(document).on('click', '#OpenAllWIEntries', function () {
$('#world_popup_entries_list').children().find('.down').click();
});
$(document).on('click', '#CloseAllWIEntries', function () {
$('#world_popup_entries_list').children().find('.up').click();
document.addEventListener('click', function (e) {
if (!(e.target instanceof HTMLElement)) return;
if (e.target.matches('#OpenAllWIEntries')) {
document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => {
toggleDrawer(drawer, true);
});
} else if (e.target.matches('#CloseAllWIEntries')) {
document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => {
toggleDrawer(drawer, false);
});
}
});
$(document).on('click', '.open_alternate_greetings', openAlternateGreetings);
/* $('#set_character_world').on('click', openCharacterWorldPopup); */
@@ -10738,7 +10748,7 @@ jQuery(async function () {
}
} break;
case 'import_tags': {
await importTags(characters[this_chid], { forceShow: true });
await importTags(characters[this_chid], { importSetting: tag_import_setting.ASK });
} break;
/*case 'delete_button':
popup_type = "del_ch";
@@ -10767,62 +10777,66 @@ jQuery(async function () {
var isManualInput = false;
var valueBeforeManualInput;
$('.range-block-counter input, .neo-range-input').on('click', function () {
$(document).on('input', '.range-block-counter input, .neo-range-input', function () {
valueBeforeManualInput = $(this).val();
console.log(valueBeforeManualInput);
})
.on('change', function (e) {
e.target.focus();
e.target.dispatchEvent(new Event('keyup'));
})
.on('keydown', function (e) {
const masterSelector = '#' + $(this).data('for');
const masterElement = $(masterSelector);
if (e.key === 'Enter') {
let manualInput = Number($(this).val());
if (isManualInput) {
//disallow manual inputs outside acceptable range
if (manualInput >= Number($(this).attr('min')) && manualInput <= Number($(this).attr('max'))) {
//if value is ok, assign to slider and update handle text and position
//newSlider.val(manualInput)
//handleSlideEvent.call(newSlider, null, { value: parseFloat(manualInput) }, 'manual');
valueBeforeManualInput = manualInput;
$(masterElement).val($(this).val()).trigger('input');
} else {
//if value not ok, warn and reset to last known valid value
toastr.warning(`Invalid value. Must be between ${$(this).attr('min')} and ${$(this).attr('max')}`);
console.log(valueBeforeManualInput);
//newSlider.val(valueBeforeManualInput)
$(this).val(valueBeforeManualInput);
}
}
}
})
.on('keyup', function () {
valueBeforeManualInput = $(this).val();
console.log(valueBeforeManualInput);
isManualInput = true;
})
//trigger slider changes when user clicks away
.on('mouseup blur', function () {
const masterSelector = '#' + $(this).data('for');
const masterElement = $(masterSelector);
});
$(document).on('change', '.range-block-counter input, .neo-range-input', function (e) {
e.target.focus();
e.target.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true }));
});
$(document).on('keydown', '.range-block-counter input, .neo-range-input', function (e) {
const masterSelector = '#' + $(this).data('for');
const masterElement = $(masterSelector);
if (e.key === 'Enter') {
let manualInput = Number($(this).val());
if (isManualInput) {
//if value is between correct range for the slider
//disallow manual inputs outside acceptable range
if (manualInput >= Number($(this).attr('min')) && manualInput <= Number($(this).attr('max'))) {
//if value is ok, assign to slider and update handle text and position
//newSlider.val(manualInput)
//handleSlideEvent.call(newSlider, null, { value: parseFloat(manualInput) }, 'manual');
valueBeforeManualInput = manualInput;
//set the slider value to input value
$(masterElement).val($(this).val()).trigger('input');
$(masterElement).val($(this).val()).trigger('input', { forced: true });
} else {
//if value not ok, warn and reset to last known valid value
toastr.warning(`Invalid value. Must be between ${$(this).attr('min')} and ${$(this).attr('max')}`);
console.log(valueBeforeManualInput);
//newSlider.val(valueBeforeManualInput)
$(this).val(valueBeforeManualInput);
}
}
isManualInput = false;
});
}
});
$(document).on('keyup', '.range-block-counter input, .neo-range-input', function () {
valueBeforeManualInput = $(this).val();
console.log(valueBeforeManualInput);
isManualInput = true;
});
//trigger slider changes when user clicks away
$(document).on('mouseup blur', '.range-block-counter input, .neo-range-input', function () {
const masterSelector = '#' + $(this).data('for');
const masterElement = $(masterSelector);
let manualInput = Number($(this).val());
if (isManualInput) {
//if value is between correct range for the slider
if (manualInput >= Number($(this).attr('min')) && manualInput <= Number($(this).attr('max'))) {
valueBeforeManualInput = manualInput;
//set the slider value to input value
$(masterElement).val($(this).val()).trigger('input', { forced: true });
} else {
//if value not ok, warn and reset to last known valid value
toastr.warning(`Invalid value. Must be between ${$(this).attr('min')} and ${$(this).attr('max')}`);
console.log(valueBeforeManualInput);
$(this).val(valueBeforeManualInput);
}
}
isManualInput = false;
});
$('.user_stats_button').on('click', function () {
userStatsHandler();