mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' into confirm_delete
This commit is contained in:
195
public/script.js
195
public/script.js
@@ -101,7 +101,10 @@ import {
|
||||
nai_settings,
|
||||
} from "./scripts/nai-settings.js";
|
||||
|
||||
import { showBookmarksButtons } from "./scripts/bookmarks.js";
|
||||
import {
|
||||
createNewBookmark,
|
||||
showBookmarksButtons
|
||||
} from "./scripts/bookmarks.js";
|
||||
|
||||
import {
|
||||
horde_settings,
|
||||
@@ -162,6 +165,7 @@ import { context_settings, loadContextTemplatesFromSettings } from "./scripts/co
|
||||
import { markdownExclusionExt } from "./scripts/showdown-exclusion.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/extensions/floating-prompt/index.js";
|
||||
import { deviceInfo } from "./scripts/RossAscends-mods.js";
|
||||
import { getRegexedString, regex_placement } from "./scripts/extensions/regex/engine.js";
|
||||
|
||||
//exporting functions and vars for mods
|
||||
export {
|
||||
@@ -238,6 +242,26 @@ export {
|
||||
// API OBJECT FOR EXTERNAL WIRING
|
||||
window["SillyTavern"] = {};
|
||||
|
||||
// Event source init
|
||||
export const event_types = {
|
||||
EXTRAS_CONNECTED: 'extras_connected',
|
||||
MESSAGE_SWIPED: 'message_swiped',
|
||||
MESSAGE_SENT: 'message_sent',
|
||||
MESSAGE_RECEIVED: 'message_received',
|
||||
MESSAGE_EDITED: 'message_edited',
|
||||
MESSAGE_DELETED: 'message_deleted',
|
||||
IMPERSONATE_READY: 'impersonate_ready',
|
||||
CHAT_CHANGED: 'chat_id_changed',
|
||||
GENERATION_STOPPED: 'generation_stopped',
|
||||
EXTENSIONS_FIRST_LOAD: 'extensions_first_load',
|
||||
SETTINGS_LOADED: 'settings_loaded',
|
||||
SETTINGS_UPDATED: 'settings_updated',
|
||||
GROUP_UPDATED: 'group_updated',
|
||||
MOVABLE_PANELS_RESET: 'movable_panels_reset',
|
||||
}
|
||||
|
||||
export const eventSource = new EventEmitter();
|
||||
|
||||
const gpt3 = new GPT3BrowserTokenizer({ type: 'gpt3' });
|
||||
hljs.addPlugin({ "before:highlightElement": ({ el }) => { el.textContent = el.innerText } });
|
||||
|
||||
@@ -322,6 +346,7 @@ const system_message_types = {
|
||||
SLASH_COMMANDS: "slash_commands",
|
||||
FORMATTING: "formatting",
|
||||
HOTKEYS: "hotkeys",
|
||||
MACROS: "macros",
|
||||
};
|
||||
|
||||
const extension_prompt_types = {
|
||||
@@ -342,6 +367,7 @@ const system_messages = {
|
||||
<li><a href="javascript:displayHelp('1')">Slash Commands</a> (or <tt>/help slash</tt>)</li>
|
||||
<li><a href="javascript:displayHelp('2')">Formatting</a> (or <tt>/help format</tt>)</li>
|
||||
<li><a href="javascript:displayHelp('3')">Hotkeys</a> (or <tt>/help hotkeys</tt>)</li>
|
||||
<li><a href="javascript:displayHelp('4')">{{Macros}}</a> (or <tt>/help macros</tt>)</li>
|
||||
</ul>
|
||||
<br><b>Still got questions left? The <a target="_blank" href="https://docs.sillytavern.app/">Official SillyTavern Documentation Website</a> has much more information!</b>`
|
||||
]
|
||||
@@ -396,6 +422,23 @@ const system_messages = {
|
||||
</ul>`
|
||||
]
|
||||
},
|
||||
macros: {
|
||||
name: systemUserName,
|
||||
force_avatar: system_avatar,
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
`System-wide Replacement Macros:
|
||||
<ul>
|
||||
<li><tt>{{user}}</tt> - your current Persona username</li>
|
||||
<li><tt>{{char}}</tt> - the Character's name</li>
|
||||
<li><tt>{{time}}</tt> - the current time</li>
|
||||
<li><tt>{{date}}</tt> - the current date</li>
|
||||
<li><tt>{{random:(args)}}</tt> - returns a random item from the list. (ex: {{random:1,2,3,4}} will return 1 of the 4 numbers at random. Works with text lists too.</li>
|
||||
</ul>`
|
||||
]
|
||||
},
|
||||
welcome:
|
||||
{
|
||||
name: systemUserName,
|
||||
@@ -479,23 +522,6 @@ const system_messages = {
|
||||
},
|
||||
};
|
||||
|
||||
export const event_types = {
|
||||
EXTRAS_CONNECTED: 'extras_connected',
|
||||
MESSAGE_SWIPED: 'message_swiped',
|
||||
MESSAGE_SENT: 'message_sent',
|
||||
MESSAGE_RECEIVED: 'message_received',
|
||||
MESSAGE_EDITED: 'message_edited',
|
||||
MESSAGE_DELETED: 'message_deleted',
|
||||
IMPERSONATE_READY: 'impersonate_ready',
|
||||
CHAT_CHANGED: 'chat_id_changed',
|
||||
GENERATION_STOPPED: 'generation_stopped',
|
||||
SETTINGS_UPDATED: 'settings_updated',
|
||||
GROUP_UPDATED: 'group_updated',
|
||||
MOVABLE_PANELS_RESET: 'movable_panels_reset',
|
||||
}
|
||||
|
||||
export const eventSource = new EventEmitter();
|
||||
|
||||
$(document).ajaxError(function myErrorHandler(_, xhr) {
|
||||
if (xhr.status == 403) {
|
||||
toastr.warning("doubleCsrf errors in console are NORMAL in this case. Just reload the page or close this tab.", "Looks like you've opened SillyTavern in another browser tab", { timeOut: 0, extendedTimeOut: 0, preventDuplicates: true });
|
||||
@@ -916,6 +942,7 @@ async function getCharacters() {
|
||||
}
|
||||
await getGroups();
|
||||
await printCharacters();
|
||||
updateCharacterCount('#rm_print_characters_block > div');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,6 +1136,11 @@ function messageFormatting(mes, ch_name, isSystem, isUser) {
|
||||
mes = mes.replaceAll(substituteParams(power_user.user_prompt_bias), "");
|
||||
}
|
||||
|
||||
const regexResult = getRegexedString(mes, regex_placement.MD_DISPLAY);
|
||||
if (regexResult) {
|
||||
mes = regexResult;
|
||||
}
|
||||
|
||||
if (power_user.auto_fix_generated_markdown) {
|
||||
mes = fixMarkdown(mes);
|
||||
}
|
||||
@@ -1484,9 +1516,28 @@ function substituteParams(content, _name1, _name2, _original) {
|
||||
content = content.replace(/<BOT>/gi, _name2);
|
||||
content = content.replace(/{{time}}/gi, moment().format('LT'));
|
||||
content = content.replace(/{{date}}/gi, moment().format('LL'));
|
||||
content = randomReplace(content);
|
||||
return content;
|
||||
}
|
||||
|
||||
function randomReplace(input, emptyListPlaceholder = '') {
|
||||
const randomPattern = /{{random:([^}]+)}}/gi;
|
||||
|
||||
return input.replace(randomPattern, (match, listString) => {
|
||||
const list = listString.split(',').map(item => item.trim()).filter(item => item.length > 0);
|
||||
|
||||
if (list.length === 0) {
|
||||
return emptyListPlaceholder;
|
||||
}
|
||||
|
||||
var rng = new Math.seedrandom('added entropy.', { entropy: true });
|
||||
const randomIndex = Math.floor(rng() * list.length);
|
||||
|
||||
//const randomIndex = Math.floor(Math.random() * list.length);
|
||||
return list[randomIndex];
|
||||
});
|
||||
}
|
||||
|
||||
function getStoppingStrings(isImpersonate, addSpace) {
|
||||
const charString = `\n${name2}:`;
|
||||
const youString = `\nYou:`;
|
||||
@@ -1588,7 +1639,7 @@ export function extractMessageBias(message) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const forbiddenMatches = ['user', 'char', 'time', 'date'];
|
||||
const forbiddenMatches = ['user', 'char', 'time', 'date', 'random'];
|
||||
const found = [];
|
||||
const rxp = /\{\{([\s\S]+?)\}\}/gm;
|
||||
//const rxp = /{([^}]+)}/g;
|
||||
@@ -1597,7 +1648,12 @@ export function extractMessageBias(message) {
|
||||
while ((curMatch = rxp.exec(message))) {
|
||||
const match = curMatch[1].trim();
|
||||
|
||||
if (forbiddenMatches.includes(match)) {
|
||||
// Ignore random pattern matches
|
||||
if (/^random:.+/i.test(match)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (forbiddenMatches.includes(match.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1715,7 +1771,7 @@ function appendToStoryString(value, prefix) {
|
||||
}
|
||||
|
||||
function isStreamingEnabled() {
|
||||
return ((main_api == 'openai' && oai_settings.stream_openai)
|
||||
return ((main_api == 'openai' && oai_settings.stream_openai && oai_settings.chat_completion_source !== chat_completion_sources.SCALE)
|
||||
|| (main_api == 'kobold' && kai_settings.streaming_kobold && kai_settings.can_use_streaming)
|
||||
|| (main_api == 'novel' && nai_settings.streaming_novel)
|
||||
|| (main_api == 'poe' && poe_settings.streaming)
|
||||
@@ -2866,6 +2922,11 @@ export function replaceBiasMarkup(str) {
|
||||
}
|
||||
|
||||
export async function sendMessageAsUser(textareaText, messageBias) {
|
||||
const regexResult = getRegexedString(textareaText, regex_placement.USER_INPUT);
|
||||
if (regexResult) {
|
||||
textareaText = regexResult;
|
||||
}
|
||||
|
||||
chat[chat.length] = {};
|
||||
chat[chat.length - 1]['name'] = name1;
|
||||
chat[chat.length - 1]['is_user'] = true;
|
||||
@@ -3446,11 +3507,21 @@ function extractMessageFromData(data) {
|
||||
}
|
||||
|
||||
function cleanUpMessage(getMessage, isImpersonate, displayIncompleteSentences = false) {
|
||||
// Append the user bias first before trimming anything else
|
||||
if (power_user.user_prompt_bias && power_user.user_prompt_bias.length !== 0) {
|
||||
// Add the prompt bias before anything else
|
||||
if (
|
||||
power_user.user_prompt_bias &&
|
||||
!isImpersonate &&
|
||||
power_user.user_prompt_bias.length !== 0
|
||||
) {
|
||||
getMessage = substituteParams(power_user.user_prompt_bias) + getMessage;
|
||||
}
|
||||
|
||||
// Regex uses vars, so add before formatting
|
||||
const regexResult = getRegexedString(getMessage, isImpersonate ? regex_placement.USER_INPUT : regex_placement.AI_OUTPUT);
|
||||
if (regexResult) {
|
||||
getMessage = regexResult;
|
||||
}
|
||||
|
||||
if (!displayIncompleteSentences && power_user.trim_sentences) {
|
||||
getMessage = end_trim_to_sentence(getMessage, power_user.include_newline);
|
||||
}
|
||||
@@ -3816,7 +3887,7 @@ async function renamePastChats(newAvatar, newValue) {
|
||||
}
|
||||
}
|
||||
|
||||
async function saveChat(chat_name, withMetadata) {
|
||||
async function saveChat(chat_name, withMetadata, mesId) {
|
||||
const metadata = { ...chat_metadata, ...(withMetadata || {}) };
|
||||
let file_name = chat_name ?? characters[this_chid].chat;
|
||||
characters[this_chid]['date_last_chat'] = Date.now();
|
||||
@@ -3837,6 +3908,11 @@ async function saveChat(chat_name, withMetadata) {
|
||||
}
|
||||
*/
|
||||
});
|
||||
|
||||
const trimmed_chat = (mesId !== undefined && mesId >= 0 && mesId < chat.length)
|
||||
? chat.slice(0, parseInt(mesId) + 1)
|
||||
: chat;
|
||||
|
||||
var save_chat = [
|
||||
{
|
||||
user_name: name1,
|
||||
@@ -3844,7 +3920,7 @@ async function saveChat(chat_name, withMetadata) {
|
||||
create_date: chat_create_date,
|
||||
chat_metadata: metadata,
|
||||
},
|
||||
...chat,
|
||||
...trimmed_chat,
|
||||
];
|
||||
return jQuery.ajax({
|
||||
type: "POST",
|
||||
@@ -4768,10 +4844,13 @@ async function getSettings(type) {
|
||||
|
||||
if (data.enable_extensions) {
|
||||
await loadExtensionSettings(settings);
|
||||
eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_checked_colab) isColab();
|
||||
|
||||
eventSource.emit(event_types.SETTINGS_LOADED);
|
||||
}
|
||||
|
||||
function selectKoboldGuiPreset() {
|
||||
@@ -4860,13 +4939,34 @@ function setCharacterBlockHeight() {
|
||||
function updateMessage(div) {
|
||||
const mesBlock = div.closest(".mes_block");
|
||||
let text = mesBlock.find(".edit_textarea").val();
|
||||
const mes = chat[this_edit_mes_id];
|
||||
let regexPlacement;
|
||||
if (mes.is_name && !mes.is_user && mes.name !== name2) {
|
||||
regexPlacement = regex_placement.SENDAS;
|
||||
} else if (mes.is_name && !mes.is_user) {
|
||||
regexPlacement = regex_placement.AI_OUTPUT;
|
||||
} else if (mes.is_name && mes.is_user) {
|
||||
regexPlacement = regex_placement.USER_INPUT;
|
||||
} else if (mes.extra?.type === "narrator") {
|
||||
regexPlacement = regex_placement.SYSTEM;
|
||||
}
|
||||
|
||||
const regexResult = getRegexedString(
|
||||
text,
|
||||
regexPlacement,
|
||||
{
|
||||
characterOverride: regexPlacement === regex_placement.SENDAS ? mes.name : undefined
|
||||
}
|
||||
);
|
||||
if (regexResult) {
|
||||
text = regexResult;
|
||||
}
|
||||
|
||||
if (power_user.trim_spaces) {
|
||||
text = text.trim();
|
||||
}
|
||||
|
||||
const bias = extractMessageBias(text);
|
||||
const mes = chat[this_edit_mes_id];
|
||||
mes["mes"] = text;
|
||||
if (mes["swipe_id"] !== undefined) {
|
||||
mes["swipes"][mes["swipe_id"]] = text;
|
||||
@@ -5189,6 +5289,7 @@ export function select_selected_character(chid) {
|
||||
$("#description_textarea").val(characters[chid].description);
|
||||
$("#character_world").val(characters[chid].data?.extensions?.world || '');
|
||||
$("#creator_notes_textarea").val(characters[chid].data?.creator_notes || characters[chid].creatorcomment);
|
||||
$("#creator_notes_spoiler").text(characters[chid].data?.creator_notes || characters[chid].creatorcomment);
|
||||
$("#character_version_textarea").val(characters[chid].data?.character_version || '');
|
||||
$("#system_prompt_textarea").val(characters[chid].data?.system_prompt || '');
|
||||
$("#post_history_instructions_textarea").val(characters[chid].data?.post_history_instructions || '');
|
||||
@@ -5257,6 +5358,7 @@ function select_rm_create() {
|
||||
$("#description_textarea").val(create_save.description);
|
||||
$('#character_world').val(create_save.world);
|
||||
$("#creator_notes_textarea").val(create_save.creator_notes);
|
||||
$("#creator_notes_spoiler").text(create_save.creator_notes);
|
||||
$("#post_history_instructions_textarea").val(create_save.post_history_instructions);
|
||||
$("#system_prompt_textarea").val(create_save.system_prompt);
|
||||
$("#tags_textarea").val(create_save.tags);
|
||||
@@ -5331,7 +5433,7 @@ function onScenarioOverrideRemoveClick() {
|
||||
$(this).closest('.scenario_override').find('.chat_scenario').val('').trigger('input');
|
||||
}
|
||||
|
||||
function callPopup(text, type, inputValue = '') {
|
||||
function callPopup(text, type, inputValue = '', okButton) {
|
||||
if (type) {
|
||||
popup_type = type;
|
||||
}
|
||||
@@ -5339,30 +5441,30 @@ function callPopup(text, type, inputValue = '') {
|
||||
$("#dialogue_popup_cancel").css("display", "inline-block");
|
||||
switch (popup_type) {
|
||||
case "avatarToCrop":
|
||||
$("#dialogue_popup_ok").text("Accept");
|
||||
$("#dialogue_popup_ok").text(okButton ?? "Accept");
|
||||
break;
|
||||
case "text":
|
||||
case "alternate_greeting":
|
||||
case "char_not_selected":
|
||||
$("#dialogue_popup_ok").text("Ok");
|
||||
$("#dialogue_popup_ok").text(okButton ?? "Ok");
|
||||
$("#dialogue_popup_cancel").css("display", "none");
|
||||
break;
|
||||
case "new_chat":
|
||||
case "confirm":
|
||||
$("#dialogue_popup_ok").text("Yes");
|
||||
$("#dialogue_popup_ok").text(okButton ?? "Yes");
|
||||
break;
|
||||
case "del_group":
|
||||
case "rename_chat":
|
||||
case "del_chat":
|
||||
default:
|
||||
$("#dialogue_popup_ok").text("Delete");
|
||||
$("#dialogue_popup_ok").text(okButton ?? "Delete");
|
||||
}
|
||||
|
||||
$("#dialogue_popup_input").val(inputValue);
|
||||
|
||||
if (popup_type == 'input') {
|
||||
$("#dialogue_popup_input").css("display", "block");
|
||||
$("#dialogue_popup_ok").text("Save");
|
||||
$("#dialogue_popup_ok").text(okButton ?? "Save");
|
||||
}
|
||||
else {
|
||||
$("#dialogue_popup_input").css("display", "none");
|
||||
@@ -5960,9 +6062,11 @@ async function createOrEditCharacter(e) {
|
||||
success: async function (html) {
|
||||
if (chat.length === 1 && !selected_group) {
|
||||
var this_ch_mes = default_ch_mes;
|
||||
|
||||
if ($("#firstmessage_textarea").val() != "") {
|
||||
this_ch_mes = $("#firstmessage_textarea").val();
|
||||
}
|
||||
|
||||
if (
|
||||
this_ch_mes !=
|
||||
$.trim(
|
||||
@@ -5973,6 +6077,13 @@ async function createOrEditCharacter(e) {
|
||||
.text()
|
||||
)
|
||||
) {
|
||||
// MARK - kingbri: Regex on character greeting message
|
||||
// May need to be placed somewhere else
|
||||
const regexResult = getRegexedString(this_ch_mes, regex_placement.AI_OUTPUT);
|
||||
if (regexResult) {
|
||||
this_ch_mes = regexResult;
|
||||
}
|
||||
|
||||
clearChat();
|
||||
chat.length = 0;
|
||||
chat[0] = {};
|
||||
@@ -6348,6 +6459,17 @@ const swipe_right = () => {
|
||||
}
|
||||
}
|
||||
|
||||
export function updateCharacterCount(characterSelector) {
|
||||
const visibleCharacters = $(characterSelector).filter(":visible");
|
||||
const visibleCharacterCount = visibleCharacters.length;
|
||||
const totalCharacterCount = $(characterSelector).length;
|
||||
|
||||
$("#rm_character_count").text(
|
||||
`(${visibleCharacterCount} / ${totalCharacterCount}) Characters`
|
||||
);
|
||||
console.log("visibleCharacters.length: " + visibleCharacters.length);
|
||||
}
|
||||
|
||||
function updateVisibleDivs(containerSelector, resizecontainer) {
|
||||
var $container = $(containerSelector);
|
||||
var $children = $container.children();
|
||||
@@ -6602,6 +6724,8 @@ $(document).ready(function () {
|
||||
});
|
||||
updateVisibleDivs('#rm_print_characters_block', true);
|
||||
}
|
||||
updateCharacterCount(selector);
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -7886,6 +8010,13 @@ $(document).ready(function () {
|
||||
$("#load_select_chat_div").css("display", "block");
|
||||
});
|
||||
|
||||
$(document).on("click", ".mes_create_bookmark", async function () {
|
||||
var selected_mes_id = $(this).closest(".mes").attr("mesid");
|
||||
if (selected_mes_id !== undefined) {
|
||||
createNewBookmark(selected_mes_id);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", ".mes_stop", function () {
|
||||
if (streamingProcessor) {
|
||||
streamingProcessor.abortController.abort();
|
||||
|
Reference in New Issue
Block a user