added hotkeys hints to /? readout

This commit is contained in:
RossAscends
2023-05-19 04:51:11 +09:00
parent 84900917a0
commit 80ccf6809f

View File

@@ -291,11 +291,22 @@ const system_messages = {
is_system: true, is_system: true,
is_name: true, is_name: true,
mes: [ mes: [
'Hi there! The following chat formatting commands are supported:', `Hi there! The following chat formatting commands are supported:
'<ol>', <ul>
'<li><tt>{{text}}</tt> sets a one-time behavioral bias for the AI. Resets when you send the next message.</li>', <li><tt>{{text}}</tt> - sets a one-time behavioral bias for the AI. Resets when you send the next message.
'</ol>', </li>
].join('') </ul>
Hotkeys/Keybinds:
<ul>
<li><tt>Up</tt> = Edit last message in chat</li>
<li><tt>Ctrl+Up</tt> = Edit last USER message in chat</li>
<li><tt>Left</tt> = swipe left</li>
<li><tt>Right</tt> = swipe right (NOTE: swipe hotkeys are disabled when chatbar has something typed into it)</li>
<li><tt>Ctrl+Left</tt> = view locally stored variables (in the browser console window)</li>
<li><tt>Enter</tt> (with chat bar selected) = send your message to AI</li>
<li><tt>Ctrl+Enter</tt> = Regenerate the last AI response</li>
</ul>`
]
}, },
welcome: welcome:
{ {
@@ -304,42 +315,42 @@ const system_messages = {
is_user: false, is_user: false,
is_name: true, is_name: true,
mes: [ mes: [
'<h2>Welcome to <span id="version_display_welcome">SillyTavern</span>!</h2>', `<h2>Welcome to <span id="version_display_welcome">SillyTavern</span>!</h2>
'<div id="version_display_welcome"></div>', <div id="version_display_welcome"></div>
'<h3>Want to Update to the latest version?</h3>', <h3>Want to Update to the latest version?</h3>
"Read the <a href='/notes/update.html' target='_blank'>instructions here</a>. Also located in your installation's base folder", Read the <a href='/notes/update.html' target='_blank'>instructions here</a>. Also located in your installation's base folder
'<hr class="sysHR">', <hr class="sysHR">
'<h3>In order to begin chatting:</h3>', <h3>In order to begin chatting:</h3>
'<ol>', <ol>
'<li>Connect to one of the supported generation APIs (the plug icon)</li>', <li>Connect to one of the supported generation APIs (the plug icon)</li>
'<li>Create or pick a character from the list (the top-right namecard icon)</li>', <li>Create or pick a character from the list (the top-right namecard icon)</li>
'</ol>', </ol>
'<hr class="sysHR">', <hr class="sysHR">
'<h3>Where to download more characters?</h3>', <h3>Where to download more characters?</h3>
'<i>(Not endorsed, your discretion is advised)</i>', <i>(Not endorsed, your discretion is advised)</i>
'<ol>', <ol>
'<li><a target="_blank" href="https://discord.gg/pygmalionai">Pygmalion AI Discord</a></li>', <li><a target="_blank" href="https://discord.gg/pygmalionai">Pygmalion AI Discord</a></li>
'<li><a target="_blank" href="https://www.characterhub.org/">CharacterHub (NSFW)</a></li>', <li><a target="_blank" href="https://www.characterhub.org/">CharacterHub (NSFW)</a></li>
'</ol>', </ol>
'<hr class="sysHR">', <hr class="sysHR">
'<h3>Where can I get help?</h3>', <h3>Where can I get help?</h3>
'Before going any further, check out the following resources:', Before going any further, check out the following resources:
'<ol>', <ol>
'<li><a target="_blank" href="/notes/readme.md">Introduction to SillyTavern</a></li>', <li><a target="_blank" href="/notes/readme.md">Introduction to SillyTavern</a></li>
'<li><a target="_blank" href="/notes/faq.md">SillyTavern FAQ</a></li>', <li><a target="_blank" href="/notes/faq.md">SillyTavern FAQ</a></li>
'<li><a target="_blank" href="/notes">SillyTavern Guidebook</a></li>', <li><a target="_blank" href="/notes">SillyTavern Guidebook</a></li>
'<li><a target="_blank" href="https://github.com/Cohee1207/TavernAI-extras/blob/main/README.md">Extras API Docs</a></li>', <li><a target="_blank" href="https://github.com/Cohee1207/TavernAI-extras/blob/main/README.md">Extras API Docs</a></li>
'<li><a target="_blank" href="https://docs.alpindale.dev/">Pygmalion AI Docs</a></li>', <li><a target="_blank" href="https://docs.alpindale.dev/">Pygmalion AI Docs</a></li>
'</ol>', </ol>
'Type <tt>/?</tt> in any chat to get help on message formatting commands.', Type <tt>/?</tt> in any chat to get help on message formatting commands.
'<hr class="sysHR">', <hr class="sysHR">
'<h3>Still have questions or suggestions left?</h3>', <h3>Still have questions or suggestions left?</h3>
'<a target="_blank" href="https://discord.gg/RZdyAEUPvj">SillyTavern Community Discord</a>', <a target="_blank" href="https://discord.gg/RZdyAEUPvj">SillyTavern Community Discord</a>
'<br/>', <br>
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern/issues">Post a GitHub issue.</a>', <a target="_blank" href="https://github.com/Cohee1207/SillyTavern/issues">Post a GitHub issue.</a>
'<br/>', <br>
'<a target="_blank" href="https://github.com/Cohee1207/SillyTavern#questions-or-suggestions">Contact the developers.</a>', <a target="_blank" href="https://github.com/Cohee1207/SillyTavern#questions-or-suggestions">Contact the developers.</a>
].join('') `].join('')
}, },
group: { group: {
name: systemUserName, name: systemUserName,
@@ -408,7 +419,7 @@ async function getClientVersion() {
let displayVersion = `SillyTavern ${data.pkgVersion}`; let displayVersion = `SillyTavern ${data.pkgVersion}`;
if (data.gitRevision && data.gitBranch) { if (data.gitRevision && data.gitBranch) {
displayVersion += ` '${data.gitBranch}' (${data.gitRevision})`; displayVersion += ` '${data.gitBranch}'(${data.gitRevision})`;
} }
$('#version_display').text(displayVersion); $('#version_display').text(displayVersion);
@@ -447,7 +458,7 @@ function getTokenCount(str, padding = undefined) {
jQuery.ajax({ jQuery.ajax({
async: false, async: false,
type: 'POST', // type: 'POST', //
url: `/tokenize_llama`, url: `/ tokenize_llama`,
data: JSON.stringify({ text: str }), data: JSON.stringify({ text: str }),
dataType: "json", dataType: "json",
contentType: "application/json", contentType: "application/json",
@@ -733,9 +744,9 @@ function updateSoftPromptsList(soft_prompts) {
// Add SPs added to Kobold // Add SPs added to Kobold
soft_prompts.forEach((prompt) => { soft_prompts.forEach((prompt) => {
if ($(`#softprompt option[value="${prompt.name}"]`).length === 0) { if ($(`#softprompt option[value = "${prompt.name}"]`).length === 0) {
$("#softprompt").append( $("#softprompt").append(
`<option value="${prompt.name}">${prompt.name}</option>` `< option value = "${prompt.name}" > ${prompt.name}</option > `
); );
if (prompt.selected) { if (prompt.selected) {
@@ -759,7 +770,7 @@ function printCharacters() {
} }
// Populate the template // Populate the template
const template = $('#character_template .character_select').clone(); const template = $('#character_template .character_select').clone();
template.attr({ 'chid': i, 'id': `CharID${i}` }); template.attr({ 'chid': i, 'id': `CharID${i} ` });
template.find('img').attr('src', this_avatar); template.find('img').attr('src', this_avatar);
template.find('.avatar').attr('title', item.avatar); template.find('.avatar').attr('title', item.avatar);
template.find('.ch_name').text(item.name); template.find('.ch_name').text(item.name);
@@ -822,7 +833,7 @@ async function getBackgrounds() {
for (const bg of getData) { for (const bg of getData) {
const thumbPath = getThumbnailUrl('bg', bg); const thumbPath = getThumbnailUrl('bg', bg);
$("#bg_menu_content").append( $("#bg_menu_content").append(
`<div class="bg_example flex-container" bgfile="${bg}" class="bg_example_img" title="${bg}" style="background-image: url('${thumbPath}');"> `< 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 bgfile="${bg}" class="bg_example_cross fa-solid fa-circle-xmark"></div>
<div class="BGSampleTitle"> <div class="BGSampleTitle">
${bg ${bg
@@ -830,7 +841,7 @@ async function getBackgrounds() {
.replace('.jpg', '') .replace('.jpg', '')
.replace('.webp', '')} .replace('.webp', '')}
</div> </div>
</div>` </div > `
); );
} }
} }
@@ -993,7 +1004,7 @@ function messageFormatting(mes, ch_name, isSystem, isUser) {
.replace(/\*\*(.+?)\*\*/g, "<b>$1</b>") .replace(/\*\*(.+?)\*\*/g, "<b>$1</b>")
.replace(/\n/g, "<br/>"); .replace(/\n/g, "<br/>");
} else if (!isSystem) { } else if (!isSystem) {
mes = mes.replace(/```[\s\S]*?```|``[\s\S]*?``|`[\s\S]*?`|(\".+?\")|(\u201C.+?\u201D)/gm, function (match, p1, p2) { mes = mes.replace(/```[\s\S]*? ```|``[\s\S]*?``|`[\s\S]*? `|(\".+?\")|(\u201C.+?\u201D)/gm, function (match, p1, p2) {
if (p1) { if (p1) {
return '<q>"' + p1.replace(/\"/g, "") + '"</q>'; return '<q>"' + p1.replace(/\"/g, "") + '"</q>';
} else if (p2) { } else if (p2) {
@@ -1016,7 +1027,7 @@ function messageFormatting(mes, ch_name, isSystem, isUser) {
} }
if (!power_user.allow_name2_display && ch_name && !isUser && !isSystem) { if (!power_user.allow_name2_display && ch_name && !isUser && !isSystem) {
mes = mes.replaceAll(`${ch_name}:`, ""); mes = mes.replaceAll(`${ch_name}: `, "");
} }
return mes; return mes;
@@ -1061,8 +1072,8 @@ function addCopyToCodeBlocks(messageElement) {
const copiedMsg = document.createElement("div"); const copiedMsg = document.createElement("div");
copiedMsg.classList.add('code-copied'); copiedMsg.classList.add('code-copied');
copiedMsg.innerText = "Copied!"; copiedMsg.innerText = "Copied!";
copiedMsg.style.top = `${event.clientY - 55}px`; copiedMsg.style.top = `${event.clientY - 55} px`;
copiedMsg.style.left = `${event.clientX - 55}px`; copiedMsg.style.left = `${event.clientX - 55} px`;
document.body.append(copiedMsg); document.body.append(copiedMsg);
setTimeout(() => { setTimeout(() => {
document.body.removeChild(copiedMsg); document.body.removeChild(copiedMsg);
@@ -1137,14 +1148,14 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
$("#chat").append(HTMLForEachMes); $("#chat").append(HTMLForEachMes);
} }
else { else {
const target = $("#chat").find(`.mes[mesid="${insertAfter}"]`); const target = $("#chat").find(`.mes[mesid = "${insertAfter}"]`);
$(HTMLForEachMes).insertAfter(target); $(HTMLForEachMes).insertAfter(target);
$(HTMLForEachMes).find('.swipe_left').css('display', 'none'); $(HTMLForEachMes).find('.swipe_left').css('display', 'none');
$(HTMLForEachMes).find('.swipe_right').css('display', 'none'); $(HTMLForEachMes).find('.swipe_right').css('display', 'none');
} }
} }
const newMessage = $(`#chat [mesid="${count_view_mes}"]`); const newMessage = $(`#chat[mesid = "${count_view_mes}"]`);
newMessage.data("isSystem", isSystem); newMessage.data("isSystem", isSystem);
if (isSystem) { if (isSystem) {
@@ -1155,17 +1166,17 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
// don't need prompt button for user // don't need prompt button for user
if (params.isUser === true) { if (params.isUser === true) {
newMessage.find(".mes_prompt").hide(); newMessage.find(".mes_prompt").hide();
console.log(`hiding prompt for user mesID ${params.mesId}`); console.log(`hiding prompt for user mesID ${params.mesId} `);
} }
//shows or hides the Prompt display button //shows or hides the Prompt display button
let mesIdToFind = Number(newMessage.attr('mesId')); let mesIdToFind = Number(newMessage.attr('mesId'));
if (itemizedPrompts.length !== 0) { if (itemizedPrompts.length !== 0) {
//console.log(`itemizedPrompt.length = ${itemizedPrompts.length}`) //console.log(`itemizedPrompt.length = ${ itemizedPrompts.length } `)
for (var i = 0; i < itemizedPrompts.length; i++) { for (var i = 0; i < itemizedPrompts.length; i++) {
if (itemizedPrompts[i].mesId === mesIdToFind) { if (itemizedPrompts[i].mesId === mesIdToFind) {
newMessage.find(".mes_prompt").show(); newMessage.find(".mes_prompt").show();
console.log(`showing prompt for mesID ${params.mesId} from ${params.characterName}`); console.log(`showing prompt for mesID ${params.mesId} from ${params.characterName} `);
} else { } else {
console.log(`no cache obj for mesID ${mesIdToFind}, hiding prompt button and continuing search`); console.log(`no cache obj for mesID ${mesIdToFind}, hiding prompt button and continuing search`);
newMessage.find(".mes_prompt").hide(); newMessage.find(".mes_prompt").hide();
@@ -1180,23 +1191,23 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
newMessage.find('.avatar img').on('error', function () { newMessage.find('.avatar img').on('error', function () {
$(this).hide(); $(this).hide();
$(this).parent().html(`<div class="missing-avatar fa-solid fa-user-slash"></div>`); $(this).parent().html(`< div class="missing-avatar fa-solid fa-user-slash" ></div > `);
}); });
if (type === 'swipe') { if (type === 'swipe') {
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).find('.mes_text').html(''); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).find('.mes_text').html('');
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).find('.mes_text').append(messageText); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).find('.mes_text').append(messageText);
appendImageToMessage(mes, $("#chat").find(`[mesid="${count_view_mes - 1}"]`)); appendImageToMessage(mes, $("#chat").find(`[mesid = "${count_view_mes - 1}"]`));
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).attr('title', title); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).attr('title', title);
if (mes.swipe_id == mes.swipes.length - 1) { if (mes.swipe_id == mes.swipes.length - 1) {
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).find('.mes_timer').text(params.timerValue); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).find('.mes_timer').text(params.timerValue);
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).find('.mes_timer').attr('title', params.timerTitle); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).find('.mes_timer').attr('title', params.timerTitle);
} else { } else {
$("#chat").find(`[mesid="${count_view_mes - 1}"]`).find('.mes_timer').html(''); $("#chat").find(`[mesid = "${count_view_mes - 1}"]`).find('.mes_timer').html('');
} }
} else { } else {
$("#chat").find(`[mesid="${count_view_mes}"]`).find('.mes_text').append(messageText); $("#chat").find(`[mesid = "${count_view_mes}"]`).find('.mes_text').append(messageText);
appendImageToMessage(mes, newMessage); appendImageToMessage(mes, newMessage);
hideSwipeButtons(); hideSwipeButtons();
count_view_mes++; count_view_mes++;
@@ -1224,10 +1235,10 @@ function formatGenerationTimer(gen_started, gen_finished) {
const start = moment(gen_started); const start = moment(gen_started);
const finish = moment(gen_finished); const finish = moment(gen_finished);
const seconds = finish.diff(start, 'seconds', true); const seconds = finish.diff(start, 'seconds', true);
const timerValue = `${seconds.toFixed(1)}s`; const timerValue = `${seconds.toFixed(1)} s`;
const timerTitle = [ const timerTitle = [
`Generation queued: ${start.format(dateFormat)}`, `Generation queued: ${start.format(dateFormat)} `,
`Reply received: ${finish.format(dateFormat)}`, `Reply received: ${finish.format(dateFormat)} `,
`Time to generate: ${seconds} seconds`, `Time to generate: ${seconds} seconds`,
].join('\n'); ].join('\n');
@@ -1256,9 +1267,9 @@ function substituteParams(content, _name1, _name2) {
} }
function getStoppingStrings(isImpersonate, addSpace) { function getStoppingStrings(isImpersonate, addSpace) {
const charString = `\n${name2}:`; const charString = `\n${name2}: `;
const youString = `\nYou:`; const youString = `\nYou: `;
const userString = `\n${name1}:`; const userString = `\n${name1}: `;
const result = isImpersonate ? [charString] : [youString]; const result = isImpersonate ? [charString] : [youString];
result.push(userString); result.push(userString);
@@ -1271,7 +1282,7 @@ function getStoppingStrings(isImpersonate, addSpace) {
const names = group.members const names = group.members
.map(x => characters.find(y => y.avatar == x)) .map(x => characters.find(y => y.avatar == x))
.filter(x => x && x.name !== name2) .filter(x => x && x.name !== name2)
.map(x => `\n${x.name}:`); .map(x => `\n${x.name}: `);
result.push(...names); result.push(...names);
} }
} }
@@ -1371,7 +1382,7 @@ function cleanGroupMessage(getMessage) {
continue; continue;
} }
const indexOfMember = getMessage.indexOf(`${name}:`); const indexOfMember = getMessage.indexOf(`${name}: `);
if (indexOfMember != -1) { if (indexOfMember != -1) {
getMessage = getMessage.substr(0, indexOfMember); getMessage = getMessage.substr(0, indexOfMember);
} }
@@ -1445,8 +1456,8 @@ class StreamingProcessor {
return; return;
} }
$(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'block' }); $(`#chat.mes[mesid = "${messageId}"].mes_stop`).css({ 'display': 'block' });
$(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'none' }); $(`#chat.mes[mesid = "${messageId}"].mes_buttons`).css({ 'display': 'none' });
} }
hideStopButton(messageId) { hideStopButton(messageId) {
@@ -1454,8 +1465,8 @@ class StreamingProcessor {
return; return;
} }
$(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'none' }); $(`#chat.mes[mesid = "${messageId}"].mes_stop`).css({ 'display': 'none' });
$(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'block' }); $(`#chat.mes[mesid = "${messageId}"].mes_buttons`).css({ 'display': 'block' });
} }
onStartStreaming(text) { onStartStreaming(text) {
@@ -1519,9 +1530,9 @@ class StreamingProcessor {
chat[messageId].is_system, chat[messageId].is_system,
chat[messageId].is_user, chat[messageId].is_user,
); );
const mesText = $(`#chat .mes[mesid="${messageId}"] .mes_text`); const mesText = $(`#chat.mes[mesid = "${messageId}"].mes_text`);
mesText.html(formattedText); mesText.html(formattedText);
$(`#chat .mes[mesid="${messageId}"] .mes_timer`).text(timePassed.timerValue).attr('title', timePassed.timerTitle); $(`#chat.mes[mesid = "${messageId}"].mes_timer`).text(timePassed.timerValue).attr('title', timePassed.timerTitle);
this.setFirstSwipe(messageId); this.setFirstSwipe(messageId);
} }
@@ -1531,7 +1542,7 @@ class StreamingProcessor {
onFinishStreaming(messageId, text) { onFinishStreaming(messageId, text) {
this.hideStopButton(this.messageId); this.hideStopButton(this.messageId);
this.onProgressStreaming(messageId, text, true); this.onProgressStreaming(messageId, text, true);
addCopyToCodeBlocks($(`#chat .mes[mesid="${messageId}"]`)); addCopyToCodeBlocks($(`#chat.mes[mesid = "${messageId}"]`));
saveChatConditional(); saveChatConditional();
activateSendButtons(); activateSendButtons();
showSwipeButtons(); showSwipeButtons();
@@ -1543,7 +1554,7 @@ class StreamingProcessor {
if (power_user.auto_swipe) { if (power_user.auto_swipe) {
function containsBlacklistedWords(str, blacklist, threshold) { function containsBlacklistedWords(str, blacklist, threshold) {
const regex = new RegExp(`\\b(${blacklist.join('|')})\\b`, 'gi'); const regex = new RegExp(`\\b(${blacklist.join('|')}) \\b`, 'gi');
const matches = str.match(regex) || []; const matches = str.match(regex) || [];
return matches.length >= threshold; return matches.length >= threshold;
} }
@@ -1753,7 +1764,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
power_user.custom_chat_separator ? power_user.custom_chat_separator : power_user.custom_chat_separator ? power_user.custom_chat_separator :
power_user.disable_examples_formatting ? '' : power_user.disable_examples_formatting ? '' :
is_pygmalion ? '<START>' : `This is how ${name2} should talk`; is_pygmalion ? '<START>' : `This is how ${name2} should talk`;
let mesExamplesArray = mesExamples.split(/<START>/gi).slice(1).map(block => `${blockHeading}\n${block.trim()}\n`); let mesExamplesArray = mesExamples.split(/<START>/gi).slice(1).map(block => `${blockHeading} \n${block.trim()} \n`);
// First message in fresh 1-on-1 chat reacts to user/character settings changes // First message in fresh 1-on-1 chat reacts to user/character settings changes
if (chat.length) { if (chat.length) {
@@ -1765,7 +1776,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
if (type === 'swipe') { if (type === 'swipe') {
coreChat.pop(); coreChat.pop();
} }
console.log(`Core/all messages: ${coreChat.length}/${chat.length}`); console.log(`Core / all messages: ${coreChat.length} /${chat.length}`);
if (main_api === 'openai') { if (main_api === 'openai') {
message_already_generated = ''; // OpenAI doesn't have multigen message_already_generated = ''; // OpenAI doesn't have multigen