mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into enable-autoselect-inputs
This commit is contained in:
458
public/script.js
458
public/script.js
@@ -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();
|
||||
|
Reference in New Issue
Block a user