Merge branch 'dev' of https://github.com/BlipRanger/SillyTavern into feature/stats

This commit is contained in:
BlipRanger
2023-07-18 09:42:11 -04:00
53 changed files with 1564 additions and 455 deletions

View File

@@ -166,7 +166,7 @@ import {
import { EventEmitter } from './scripts/eventemitter.js';
import { context_settings, loadContextTemplatesFromSettings } from "./scripts/context-template.js";
import { markdownExclusionExt } from "./scripts/showdown-exclusion.js";
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/extensions/floating-prompt/index.js";
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/authors-note.js";
import { deviceInfo } from "./scripts/RossAscends-mods.js";
import { getRegexedString, regex_placement } from "./scripts/extensions/regex/engine.js";
@@ -365,7 +365,7 @@ const system_messages = {
is_user: false,
is_system: true,
is_name: true,
mes: [
mes:
`Hello there! Please select the help topic you would like to learn more about:
<ul>
<li><a href="javascript:displayHelp('1')">Slash Commands</a> (or <tt>/help slash</tt>)</li>
@@ -374,7 +374,6 @@ const system_messages = {
<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>`
]
},
slash_commands: {
name: systemUserName,
@@ -390,7 +389,7 @@ const system_messages = {
is_user: false,
is_system: true,
is_name: true,
mes: [
mes:
`Hotkeys/Keybinds:
<ul>
<li><tt>Up</tt> = Edit last message in chat</li>
@@ -404,7 +403,6 @@ const system_messages = {
<li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li>
<li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li>
</ul>`
]
},
formatting: {
name: systemUserName,
@@ -412,7 +410,7 @@ const system_messages = {
is_user: false,
is_system: true,
is_name: true,
mes: [
mes:
`Text formatting commands:
<ul>
<li><tt>{{text}}</tt> - sets a one-time behavioral bias for the AI. Resets when you send the next message.</li>
@@ -424,7 +422,6 @@ const system_messages = {
<li><tt>$$ text $$</tt> - renders a LaTeX formula (if enabled)</li>
<li><tt>$ text $</tt> - renders an AsciiMath formula (if enabled)</li>
</ul>`
]
},
macros: {
name: systemUserName,
@@ -432,7 +429,7 @@ const system_messages = {
is_user: false,
is_system: true,
is_name: true,
mes: [
mes:
`System-wide Replacement Macros:
<ul>
<li><tt>{{user}}</tt> - your current Persona username</li>
@@ -443,7 +440,6 @@ const system_messages = {
<li><tt>{{idle_duration}}</tt> - the time since the last user message was sent</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:
{
@@ -554,6 +550,10 @@ async function getClientVersion() {
}
function getTokenCount(str, padding = undefined) {
if (typeof str !== 'string') {
return 0;
}
let tokenizerType = power_user.tokenizer;
if (main_api === 'openai') {
@@ -971,22 +971,25 @@ async function getBackgrounds() {
const getData = await response.json();
//background = getData;
//console.log(getData.length);
$("#bg_menu_content").empty();
for (const bg of getData) {
const thumbPath = getThumbnailUrl('bg', bg);
$("#bg_menu_content").append(
`<div class="bg_example flex-container" bgfile="${bg}" class="bg_example_img" title="${bg}" style="background-image: url('${thumbPath}');">
<div bgfile="${bg}" class="bg_example_cross fa-solid fa-circle-xmark"></div>
<div class="BGSampleTitle">
${bg
.replace('.png', '')
.replace('.jpg', '')
.replace('.webp', '')}
</div>
</div>`
);
const template = getBackgroundFromTemplate(bg);
$("#bg_menu_content").append(template);
}
}
}
function getBackgroundFromTemplate(bg) {
const thumbPath = getThumbnailUrl('bg', bg);
const template = $('#background_template .bg_example').clone();
template.attr('bgfile', bg);
template.attr('title', bg);
template.find('.bg_button').attr('bgfile', bg);
template.css('background-image', `url('${thumbPath}')`);
template.find('.BGSampleTitle').text(bg.slice(0, bg.lastIndexOf('.')));
return template;
}
async function isColab() {
is_checked_colab = true;
const response = await fetch("/iscolab", {
@@ -1110,6 +1113,7 @@ function clearChat() {
$('.zoomed_avatar[forChar]').remove();
} else { console.debug('saw no avatars') }
itemizedPrompts = [];
chat_metadata = {};
}
async function deleteLastMessage() {
@@ -1530,7 +1534,7 @@ function substituteParams(content, _name1, _name2, _original) {
_name1 = _name1 ?? name1;
_name2 = _name2 ?? name2;
if (!content) {
return ''
return '';
}
// Replace {{original}} with the original message
@@ -1548,6 +1552,11 @@ function substituteParams(content, _name1, _name2, _original) {
content = content.replace(/{{time}}/gi, moment().format('LT'));
content = content.replace(/{{date}}/gi, moment().format('LL'));
content = content.replace(/{{idle_duration}}/gi, () => getTimeSinceLastMessage());
content = content.replace(/{{time_UTC([-+]\d+)}}/gi, (_, offset) => {
const utcOffset = parseInt(offset, 10);
const utcTime = moment().utc().utcOffset(utcOffset).format('LT');
return utcTime;
});
content = randomReplace(content);
return content;
}
@@ -1909,8 +1918,9 @@ class StreamingProcessor {
onProgressStreaming(messageId, text, isFinal) {
const isImpersonate = this.type == "impersonate";
const isContinue = this.type == "continue";
text = this.removePrefix(text);
let processedText = cleanUpMessage(text, isImpersonate, !isFinal);
let processedText = cleanUpMessage(text, isImpersonate, isContinue, !isFinal);
let result = extractNameFromMessage(processedText, this.force_name2, isImpersonate);
let isName = result.this_mes_is_name;
processedText = result.getMessage;
@@ -2089,6 +2099,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
// OpenAI doesn't need instruct mode. Use OAI main prompt instead.
const isInstruct = power_user.instruct.enabled && main_api !== 'openai';
const isImpersonate = type == "impersonate";
const isContinue = type == 'continue';
message_already_generated = isImpersonate ? `${name1}: ` : `${name2}: `;
// Name for the multigen prefix
@@ -2265,6 +2276,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
//////////////////////////////////
let chat2 = [];
let continue_mag = '';
for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) {
// For OpenAI it's only used in WI
if (main_api == 'openai' && (!world_info || world_info.length === 0)) {
@@ -2275,8 +2287,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct);
// Do not suffix the message for continuation
if (i === 0 && type == 'continue') {
if (i === 0 && isContinue) {
chat2[i] = chat2[i].slice(0, chat2[i].lastIndexOf(coreChat[j].mes) + coreChat[j].mes.length);
continue_mag = coreChat[j].mes;
}
}
@@ -2355,7 +2368,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
}
let cyclePrompt = '';
if (type == 'continue') {
if (isContinue) {
cyclePrompt = chat2.shift();
}
@@ -2404,15 +2417,16 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
console.debug('calling runGenerate');
streamingProcessor = isStreamingEnabled() ? new StreamingProcessor(type, force_name2) : false;
if (type == 'continue') {
if (isContinue) {
// Coping mechanism for OAI spacing
if ((main_api === 'openai' || main_api === 'poe') && !cyclePrompt.endsWith(' ')) {
cyclePrompt += ' ';
continue_mag += ' ';
}
// Save reply does add cycle text to the prompt, so it's not needed here
streamingProcessor && (streamingProcessor.firstMessageText = '');
message_already_generated = cyclePrompt;
message_already_generated = continue_mag;
tokens_already_generated = 1; // Multigen copium
}
@@ -2539,7 +2553,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
console.debug(`A prompt bias was found: ${promptBias}`);
mesSendString += `${name2}: ${promptBias}`;
}
} else if (power_user.user_prompt_bias) {
} else if (power_user.user_prompt_bias && !isImpersonate && !isInstruct) {
console.debug(`A prompt bias was found without character's name appended: ${promptBias}`);
mesSendString += substituteParams(power_user.user_prompt_bias);
}
@@ -2765,8 +2779,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
hideSwipeButtons();
let getMessage = await streamingProcessor.generate();
if (type == 'continue') {
getMessage = message_already_generated + getMessage;
if (isContinue) {
getMessage = continue_mag + getMessage;
}
if (streamingProcessor && !streamingProcessor.isStopped && streamingProcessor.isFinished) {
@@ -2804,7 +2818,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
({ type, getMessage } = saveReply('append', getMessage, this_mes_is_name, title));
}
} else {
let chunk = cleanUpMessage(message_already_generated, true, true);
let chunk = cleanUpMessage(message_already_generated, true, isContinue, true);
let extract = extractNameFromMessage(chunk, force_name2, isImpersonate);
$('#send_textarea').val(extract.getMessage).trigger('input');
}
@@ -2828,12 +2842,12 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
getMessage = message_already_generated.substring(substringStart);
}
if (type == 'continue') {
getMessage = message_already_generated + getMessage;
if (isContinue) {
getMessage = continue_mag + getMessage;
}
//Formating
getMessage = cleanUpMessage(getMessage, isImpersonate);
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue);
let this_mes_is_name;
({ this_mes_is_name, getMessage } = extractNameFromMessage(getMessage, force_name2, isImpersonate));
@@ -2945,6 +2959,10 @@ function getNextMessageId(type) {
}
export function getBiasStrings(textareaText, type) {
if (type == 'impersonate') {
return { messageBias: '', promptBias: '', isUserPromptBias: false };
}
let promptBias = '';
let messageBias = extractMessageBias(textareaText);
@@ -3217,7 +3235,8 @@ function promptItemize(itemizedPrompts, requestedMesId) {
//charDescriptionTokens +
//charPersonalityTokens +
//allAnchorsTokens +
//worldInfoStringTokens +
worldInfoStringTokens +
afterScenarioAnchorTokens +
examplesStringTokens;
// OAI doesn't use padding
thisPrompt_padding = 0;
@@ -3248,7 +3267,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
if (this_main_api == 'openai') {
//console.log('-- applying % on OAI tokens');
var oaiStartTokensPercentage = ((oaiStartTokens / (finalPromptTokens)) * 100).toFixed(2);
var storyStringTokensPercentage = ((oaiPromptTokens / (finalPromptTokens)) * 100).toFixed(2);
var storyStringTokensPercentage = (((examplesStringTokens + afterScenarioAnchorTokens + oaiPromptTokens) / (finalPromptTokens)) * 100).toFixed(2);
var ActualChatHistoryTokensPercentage = ((ActualChatHistoryTokens / (finalPromptTokens)) * 100).toFixed(2);
var promptBiasTokensPercentage = ((oaiBiasTokens / (finalPromptTokens)) * 100).toFixed(2);
var worldInfoStringTokensPercentage = ((worldInfoStringTokens / (finalPromptTokens)) * 100).toFixed(2);
@@ -3605,11 +3624,12 @@ function extractMessageFromData(data) {
}
}
function cleanUpMessage(getMessage, isImpersonate, displayIncompleteSentences = false) {
function cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncompleteSentences = false) {
// Add the prompt bias before anything else
if (
power_user.user_prompt_bias &&
!isImpersonate &&
!isContinue &&
power_user.user_prompt_bias.length !== 0
) {
getMessage = substituteParams(power_user.user_prompt_bias) + getMessage;
@@ -5170,7 +5190,10 @@ function messageEditAuto(div) {
}
async function messageEditDone(div) {
const { mesBlock, text, mes, bias } = updateMessage(div);
let { mesBlock, text, mes, bias } = updateMessage(div);
if (this_edit_mes_id == 0) {
text = substituteParams(text);
}
mesBlock.find(".mes_text").empty();
mesBlock.find(".mes_edit_buttons").css("display", "none");
@@ -5681,11 +5704,7 @@ function read_bg_load(input) {
"background-image",
`url("${e.target.result}")`
);
$("#form_bg_download").after(
`<div class="bg_example" bgfile="${html}" style="background-image: url('${getThumbnailUrl('bg', html)}');">
<div class="bg_example_cross fa-solid fa-circle-xmark"></div>
</div>`
);
$("#form_bg_download").after(getBackgroundFromTemplate(html));
},
error: function (jqXHR, exception) {
console.log(exception);
@@ -6813,6 +6832,18 @@ async function doImpersonate() {
$("#option_impersonate").trigger('click', { fromSlashCommand: true })
}
async function doDeleteChat() {
$("#option_select_chat").trigger('click', { fromSlashCommand: true })
await delay(100)
let currentChatDeleteButton = $(".select_chat_block[highlight='true']").parent().find('.PastChat_cross')
$(currentChatDeleteButton).trigger('click', { fromSlashCommand: true })
await delay(1)
$("#dialogue_popup_ok").trigger('click')
//200 delay needed let the past chat view reshow first
await delay(200)
$("#select_chat_cross").trigger('click')
}
const isPwaMode = window.navigator.standalone;
if (isPwaMode) { $("body").addClass('PWA') }
@@ -6836,6 +6867,7 @@ $(document).ready(function () {
registerSlashCommand('dupe', DupeChar, [], " duplicates the currently selected character", true, true);
registerSlashCommand('api', connectAPISlash, [], "(kobold, horde, novel, ooba, oai, claude, poe, windowai) connect to an API", true, true);
registerSlashCommand('impersonate', doImpersonate, ['imp'], "- calls an impersonation response", true, true);
registerSlashCommand('delchat', doDeleteChat, [], "- deletes the current chat", true, true);
setTimeout(function () {
@@ -7069,6 +7101,41 @@ $(document).ready(function () {
});
});
$(document).on('click', '.bg_example_edit', async function (e) {
e.stopPropagation();
const old_bg = $(this).attr('bgfile');
if (!old_bg) {
console.debug('no bgfile');
return;
}
const fileExtension = old_bg.split('.').pop();
const old_bg_extensionless = old_bg.replace(`.${fileExtension}`, '');
const new_bg_extensionless = await callPopup('<h3>Enter new background name:</h3>', 'input', old_bg_extensionless);
const new_bg = `${new_bg_extensionless}.${fileExtension}`;
if (old_bg_extensionless === new_bg_extensionless) {
console.debug('new_bg === old_bg');
return;
}
const data = { old_bg, new_bg };
const response = await fetch('/renamebackground', {
method: 'POST',
headers:getRequestHeaders(),
body: JSON.stringify(data),
cache: 'no-cache',
});
if (response.ok) {
await getBackgrounds();
} else {
toastr.warning('Failed to rename background');
}
});
$(document).on("click", ".bg_example_cross", function (e) {
e.stopPropagation();
bg_file_for_del = $(this);
@@ -7080,7 +7147,7 @@ $(document).ready(function () {
$(document).on("click", ".PastChat_cross", function () {
chat_file_for_del = $(this).attr('file_name');
console.log('detected cross click for' + chat_file_for_del);
console.debug('detected cross click for' + chat_file_for_del);
popup_type = "del_chat";
callPopup("<h3>Delete the Chat File?</h3>");
});
@@ -7231,7 +7298,6 @@ $(document).ready(function () {
chat_metadata = {};
characters[this_chid].chat = name2 + " - " + humanizedDateTime();
$("#selected_chat_pole").val(characters[this_chid].chat);
saveCharacterDebounced();
getChat();
}
}
@@ -7540,15 +7606,20 @@ $(document).ready(function () {
var id = $(this).attr("id");
if (id == "option_select_chat") {
if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press)) {
if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press) || fromSlashCommand) {
displayPastChats();
$("#shadow_select_chat_popup").css("display", "block");
$("#shadow_select_chat_popup").css("opacity", 0.0);
$("#shadow_select_chat_popup").transition({
opacity: 1.0,
duration: animation_duration,
easing: animation_easing,
});
//this is just to avoid the shadow for past chat view when using /delchat
//however, the dialog popup still gets one..
if (!fromSlashCommand) {
console.log('displaying shadow')
$("#shadow_select_chat_popup").css("display", "block");
$("#shadow_select_chat_popup").css("opacity", 0.0);
$("#shadow_select_chat_popup").transition({
opacity: 1.0,
duration: animation_duration,
easing: animation_easing,
});
}
}
}
@@ -8333,7 +8404,7 @@ $(document).ready(function () {
var icon = $(this).find('.inline-drawer-icon');
icon.toggleClass('down up');
icon.toggleClass('fa-circle-chevron-down fa-circle-chevron-up');
$(this).closest('.inline-drawer').find('.inline-drawer-content').slideToggle();
$(this).closest('.inline-drawer').find('.inline-drawer-content').stop().slideToggle();
});
$(document).on('click', '.mes .avatar', function () {