Merge branch 'staging' into slash-command-enums

This commit is contained in:
Wolfsblvt
2024-06-17 07:06:26 +02:00
39 changed files with 2183 additions and 1699 deletions

View File

@@ -79,7 +79,7 @@
<span data-i18n="Ask every time">Ask every time</span>
</label>
</div>
<label for="caption_template"><span data-i18n="Message Template">Message Template</span> <small><span data-i18n="(use ">(use </span> <code>&lcub;&lcub;caption&rcub;&rcub;</code> <span data-i18n="macro)">macro)</span></small></label>
<label for="caption_template"><span data-i18n="Message Template">Message Template</span> <small><span data-i18n="(use _space">(use </span> <code>&lcub;&lcub;caption&rcub;&rcub;</code> <span data-i18n="macro)">macro)</span></small></label>
<textarea id="caption_template" class="text_pole" rows="2" placeholder="&lt; Use default &gt;">${TEMPLATE_DEFAULT}</textarea>
<label class="checkbox_label margin-bot-10px" for="caption_refine_mode">
<input id="caption_refine_mode" type="checkbox" class="checkbox">

View File

@@ -1,4 +1,4 @@
import { callPopup, eventSource, event_types, generateQuietPrompt, getRequestHeaders, online_status, saveSettingsDebounced, substituteParams, substituteParamsExtended } from '../../../script.js';
import { callPopup, eventSource, event_types, generateQuietPrompt, getRequestHeaders, online_status, saveSettingsDebounced, substituteParams, substituteParamsExtended, system_message_types } from '../../../script.js';
import { dragElement, isMobile } from '../../RossAscends-mods.js';
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';
import { loadMovingUIState, power_user } from '../../power-user.js';
@@ -1191,12 +1191,7 @@ function getLastCharacterMessage() {
const reversedChat = context.chat.slice().reverse();
for (let mes of reversedChat) {
if (mes.is_user || mes.is_system) {
continue;
}
const character = context.characters.find(x => x.avatar == mes.original_avatar || (mes.force_avatar && mes.force_avatar.includes(encodeURIComponent(x.avatar))));
if (!character) {
if (mes.is_user || mes.is_system || mes.extra?.type === system_message_types.NARRATOR) {
continue;
}

View File

@@ -44,7 +44,7 @@
</div>
<div class="expression_custom_block m-b-1 m-t-1">
<label for="expression_custom" data-i18n="Custom Expressions">Custom Expressions</label>
<small><span data-i18n="Can be set manually or with an ">Can be set manually or with an </span><tt>/emote</tt><span data-i18n=" slash command."> slash command.</span></small>
<small><span data-i18n="Can be set manually or with an _space">Can be set manually or with an </span><tt>/emote</tt><span data-i18n="space_ slash command."> slash command.</span></small>
<div class="flex-container">
<select id="expression_custom" class="flex1 margin0"><select>
<i id="expression_custom_add" class="menu_button fa-solid fa-plus margin0" title="Add"></i>
@@ -59,7 +59,7 @@
<small data-i18n="You are in offline mode. Click on the image below to set the expression.">You are in offline mode. Click on the image below to set the expression.</small>
</div>
<label for="expression_override" data-i18n="Sprite Folder Override">Sprite Folder Override</label>
<small><span data-i18n="Use a forward slash to specify a subfolder. Example: ">Use a forward slash to specify a subfolder. Example: </span><tt>Bob/formal</tt></small>
<small><span data-i18n="Use a forward slash to specify a subfolder. Example: _space">Use a forward slash to specify a subfolder. Example: </span><tt>Bob/formal</tt></small>
<div class="flex-container flexnowrap">
<input id="expression_override" type="text" class="text_pole" placeholder="Override folder name" />
<input id="expression_override_button" class="menu_button" type="submit" value="Submit" />
@@ -74,7 +74,7 @@
<span data-i18n="Remove all image overrides">Remove all image overrides</span>
</div>
</div>
<p class="hint"><b data-i18n="Hint:">Hint:</b> <i><span data-i18n="Create new folder in the ">Create new folder in the </span><b>/characters/</b> <span data-i18n="folder of your user data directory and name it as the name of the character.">folder of your user data directory and name it as the name of the character.</span>
<p class="hint"><b data-i18n="Hint:">Hint:</b> <i><span data-i18n="Create new folder in the _space">Create new folder in the </span><b>/characters/</b> <span data-i18n="folder of your user data directory and name it as the name of the character.">folder of your user data directory and name it as the name of the character.</span>
<span data-i18n="Put images with expressions there. File names should follow the pattern:">Put images with expressions there. File names should follow the pattern: </span><tt data-i18n="expression_label_pattern">[expression_label].[image_format]</tt></i></p>
<h3 id="image_list_header">
<strong data-i18n="Sprite set:">Sprite set:</strong>&nbsp;<span id="image_list_header_name"></span>

View File

@@ -24,7 +24,7 @@
<textarea id="memory_contents" class="text_pole textarea_compact" rows="6" data-i18n="[placeholder]ext_sum_memory_placeholder" placeholder="Summary will be generated here..."></textarea>
<div class="memory_contents_controls">
<div id="memory_force_summarize" data-summary-source="main" class="menu_button menu_button_icon" data-i18n="[title]ext_sum_force_tip" title="Trigger a summary update right now." data-i18n="Trigger a summary update right now.">
<div id="memory_force_summarize" data-summary-source="main" class="menu_button menu_button_icon" title="Trigger a summary update right now." data-i18n="[title]ext_sum_force_tip">
<i class="fa-solid fa-database"></i>
<span data-i18n="ext_sum_force_text">Summarize now</span>
</div>

View File

@@ -8,11 +8,11 @@
</div>
<div class="inline-drawer-content">
<div class="flex-container">
<div id="open_regex_editor" class="menu_button menu_button_icon" title="New global regex script">
<div id="open_regex_editor" class="menu_button menu_button_icon" data-i18n="[title]ext_regex_new_global_script_desc" title="New global regex script">
<i class="fa-solid fa-pen-to-square"></i>
<small data-i18n="ext_regex_new_global_script">+ Global</small>
</div>
<div id="open_scoped_editor" class="menu_button menu_button_icon" title="New scoped regex script">
<div id="open_scoped_editor" class="menu_button menu_button_icon" data-i18n="[title]ext_regex_new_scoped_script_desc" title="New scoped regex script">
<i class="fa-solid fa-address-card"></i>
<small data-i18n="ext_regex_new_scoped_script">+ Scoped</small>
</div>
@@ -39,7 +39,7 @@
<label id="toggle_scoped_regex" class="checkbox flex-container" for="regex_scoped_toggle">
<input type="checkbox" id="regex_scoped_toggle" class="enable_scoped" />
<span class="regex-toggle-on fa-solid fa-toggle-on fa-lg" title="Disallow using scoped regex"></span>
<span class="regex-toggle-off fa-solid fa-toggle-off fa-lg" title="Allow using scoped regex"></span>
<span class="regex-toggle-off fa-solid fa-toggle-off fa-lg" data-i18n="[title]ext_regex_allow_scoped" title="Allow using scoped regex"></span>
</label>
</div>
<small data-i18n="ext_regex_scoped_scripts_desc">

View File

@@ -714,6 +714,10 @@ function onChatChanged() {
}
function adjustElementScrollHeight(){
if (!$('.sd_settings').is(':visible')) {
return;
}
resetScrollHeight($('#sd_prompt_prefix'));
resetScrollHeight($('#sd_negative_prompt'));
resetScrollHeight($('#sd_character_prompt'));

View File

@@ -0,0 +1 @@
<h3 data-i18n="ext_translate_delete_confirm_1">Are you sure?</h3><span data-i18n="ext_translate_delete_confirm_2">This will remove translated text from all messages in the current chat. This action cannot be undone.</span>

View File

@@ -1,7 +1,7 @@
<div class="translation_settings">
<div class="inline-drawer">
<div class="inline-drawer-toggle inline-drawer-header">
<b data-i18n="Chat Translation">Chat Translation</b>
<b data-i18n="ext_translate_title">Chat Translation</b>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
</div>
<div class="inline-drawer-content">

View File

@@ -10,13 +10,12 @@ import {
substituteParams,
updateMessageBlock,
} from '../../../script.js';
import { extension_settings, getContext } from '../../extensions.js';
import { extension_settings, getContext, renderExtensionTemplateAsync } from '../../extensions.js';
import { findSecret, secret_state, writeSecret } from '../../secrets.js';
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
import { splitRecursive } from '../../utils.js';
import { renderTemplateAsync } from '../../templates.js';
export const autoModeOptions = {
NONE: 'none',
@@ -505,7 +504,8 @@ async function onTranslateChatClick() {
}
async function onTranslationsClearClick() {
const confirm = await callPopup('<h3>Are you sure?</h3>This will remove translated text from all messages in the current chat. This action cannot be undone.', 'confirm');
const popupHtml = await renderExtensionTemplateAsync('translate', 'deleteConfirmation');
const confirm = await callPopup(popupHtml, 'confirm');
if (!confirm) {
return;
@@ -564,9 +564,9 @@ const handleMessageEdit = createEventHandler(translateMessageEdit, () => true);
window['translate'] = translate;
jQuery(async () => {
const html = await renderTemplateAsync('translateIndex');
const html = await renderExtensionTemplateAsync('translate', 'index');
const buttonHtml = await renderTemplateAsync('translateButtons');
const buttonHtml = await renderExtensionTemplateAsync('translate', 'buttons');
$('#extensionsMenu').append(buttonHtml);
$('#extensions_settings2').append(html);
$('#translate_chat').on('click', onTranslateChatClick);

View File

@@ -70,6 +70,7 @@ import { saveLogprobsForActiveMessage } from './logprobs.js';
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
import { SlashCommand } from './slash-commands/SlashCommand.js';
import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
import { renderTemplateAsync } from './templates.js';
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
export {
@@ -3702,8 +3703,8 @@ function onSettingsPresetChange() {
preset.assistant_impersonation = preset.assistant_prefill;
}
const updateInput = (selector, value) => $(selector).val(value).trigger('input');
const updateCheckbox = (selector, value) => $(selector).prop('checked', value).trigger('input');
const updateInput = (selector, value) => $(selector).val(value).trigger('input', { source: 'preset' });
const updateCheckbox = (selector, value) => $(selector).prop('checked', value).trigger('input', { source: 'preset' });
// Allow subscribers to alter the preset before applying deltas
eventSource.emit(event_types.OAI_PRESET_CHANGED_BEFORE, {
@@ -4412,23 +4413,8 @@ function updateScaleForm() {
}
}
function onCustomizeParametersClick() {
const template = $(`
<div class="flex-container flexFlowColumn height100p">
<h3>Additional Parameters</h3>
<div class="flex1 flex-container flexFlowColumn">
<h4>Include Body Parameters</h4>
<textarea id="custom_include_body" class="flex1" placeholder="Parameters to be included in the Chat Completion request body (YAML object)&#10;&#10;Example:&#10;- top_k: 20&#10;- repetition_penalty: 1.1"></textarea>
</div>
<div class="flex1 flex-container flexFlowColumn">
<h4>Exclude Body Parameters</h4>
<textarea id="custom_exclude_body" class="flex1" placeholder="Parameters to be excluded from the Chat Completion request body (YAML array)&#10;&#10;Example:&#10;- frequency_penalty&#10;- presence_penalty"></textarea>
</div>
<div class="flex1 flex-container flexFlowColumn">
<h4>Include Request Headers</h4>
<textarea id="custom_include_headers" class="flex1" placeholder="Additional headers for Chat Completion requests (YAML object)&#10;&#10;Example:&#10;- CustomHeader: custom-value&#10;- AnotherHeader: custom-value"></textarea>
</div>
</div>`);
async function onCustomizeParametersClick() {
const template = $(await renderTemplateAsync('customEndpointAdditionalParameters'));
template.find('#custom_include_body').val(oai_settings.custom_include_body).on('input', function () {
oai_settings.custom_include_body = String($(this).val());
@@ -4877,9 +4863,11 @@ $(document).ready(async function () {
eventSource.emit(event_types.CHATCOMPLETION_SOURCE_CHANGED, oai_settings.chat_completion_source);
});
$('#oai_max_context_unlocked').on('input', function () {
$('#oai_max_context_unlocked').on('input', function (_e, data) {
oai_settings.max_context_unlocked = !!$(this).prop('checked');
$('#chat_completion_source').trigger('change');
if (data?.source !== 'preset') {
$('#chat_completion_source').trigger('change');
}
saveSettingsDebounced();
});

View File

@@ -45,7 +45,7 @@ import { hideChatMessageRange } from './chats.js';
import { extension_settings, getContext, saveMetadataDebounced } from './extensions.js';
import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
import { chat_completion_sources, oai_settings } from './openai.js';
import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';
import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, user_avatar } from './personas.js';
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
@@ -116,12 +116,13 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
aliases: ['background'],
returns: 'the current background',
unnamedArgumentList: [
SlashCommandArgument.fromProps({ description: 'filename',
SlashCommandArgument.fromProps({
description: 'filename',
typeList: [ARGUMENT_TYPE.STRING],
isRequired: true,
enumProvider: ()=>[...document.querySelectorAll('.bg_example')]
.map((it)=>new SlashCommandEnumValue(it.getAttribute('bgfile')))
.filter(it=>it.value?.length)
enumProvider: () => [...document.querySelectorAll('.bg_example')]
.map((it) => new SlashCommandEnumValue(it.getAttribute('bgfile')))
.filter(it => it.value?.length)
,
}),
],
@@ -327,12 +328,13 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
name: 'go',
callback: goToCharacterCallback,
unnamedArgumentList: [
SlashCommandArgument.fromProps({ description: 'name',
SlashCommandArgument.fromProps({
description: 'name',
typeList: [ARGUMENT_TYPE.STRING],
isRequired: true,
enumProvider: ()=>[
...characters.map(it=>new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
...groups.map(it=>new SlashCommandEnumValue(it.name, null, 'variable', 'G')),
enumProvider: () => [
...characters.map(it => new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
...groups.map(it => new SlashCommandEnumValue(it.name, null, 'variable', 'G')),
],
}),
],
@@ -376,11 +378,12 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
name: 'ask',
callback: askCharacter,
namedArgumentList: [
SlashCommandNamedArgument.fromProps({ name: 'name',
SlashCommandNamedArgument.fromProps({
name: 'name',
description: 'character name',
typeList: [ARGUMENT_TYPE.STRING],
isRequired: true,
enumProvider: ()=>characters.map(it=>new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
enumProvider: () => characters.map(it => new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
}),
],
unnamedArgumentList: [
@@ -1205,6 +1208,30 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
],
helpString: 'Sets the model for the current API. Gets the current model name if no argument is provided.',
}));
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
name: 'setpromptentry',
aliases: ['setpromptentries'],
callback: setPromptEntryCallback,
namedArgumentList: [
new SlashCommandNamedArgument(
'identifier', 'Prompt entry identifier(s) to target', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], false, true,
),
new SlashCommandNamedArgument(
'name', 'Prompt entry name(s) to target', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], false, true,
),
],
unnamedArgumentList: [
SlashCommandArgument.fromProps({
description: 'Set entry/entries on or off',
typeList: [ARGUMENT_TYPE.STRING],
isRequired: true,
acceptsMultiple: false,
defaultValue: 'toggle', // unnamed arguments don't support default values yet
enumList: ['on', 'off', 'toggle'],
}),
],
helpString: 'Sets the specified prompt manager entry/entries on or off.',
}));
registerVariableCommands();
@@ -2827,6 +2854,85 @@ function modelCallback(_, model) {
}
}
/**
* Sets state of prompt entries (toggles) either via identifier/uuid or name.
* @param {object} args Object containing arguments
* @param {string} args.identifier Select prompt entry using an identifier (uuid)
* @param {string} args.name Select prompt entry using name
* @param {string} targetState The targeted state of the entry/entries
* @returns {String} empty string
*/
function setPromptEntryCallback(args, targetState) {
// needs promptManager to manipulate prompt entries
const promptManager = setupChatCompletionPromptManager(oai_settings);
const prompts = promptManager.serviceSettings.prompts;
function parseArgs(arg) {
const list = [];
try {
const parsedArg = JSON.parse(arg);
list.push(...Array.isArray(parsedArg) ? parsedArg : [arg]);
} catch {
list.push(arg);
}
return list;
}
let identifiersList = parseArgs(args.identifier);
let nameList = parseArgs(args.name);
// Check if identifiers exists in prompt, else remove from list
if (identifiersList.length !== 0) {
identifiersList = identifiersList.filter(identifier => prompts.some(prompt => prompt.identifier === identifier));
}
if (nameList.length !== 0) {
nameList.forEach(name => {
// one name could potentially have multiple entries, find all identifiers that match given name
let identifiers = [];
prompts.forEach(entry => {
if (entry.name === name) {
identifiers.push(entry.identifier);
}
});
identifiersList = identifiersList.concat(identifiers);
});
}
// Remove duplicates to allow consistent 'toggle'
identifiersList = [...new Set(identifiersList)];
if (identifiersList.length === 0) return '';
// logic adapted from PromptManager.js, handleToggle
const getPromptOrderEntryState = (promptOrderEntry) => {
if (['toggle', 't', ''].includes(targetState.trim().toLowerCase())) {
return !promptOrderEntry.enabled;
}
if (isTrueBoolean(targetState)) {
return true;
}
if (isFalseBoolean(targetState)) {
return false;
}
return promptOrderEntry.enabled;
};
identifiersList.forEach(promptID => {
const promptOrderEntry = promptManager.getPromptOrderEntry(promptManager.activeCharacter, promptID);
const counts = promptManager.tokenHandler.getCounts();
counts[promptID] = null;
promptOrderEntry.enabled = getPromptOrderEntryState(promptOrderEntry);
});
// no need to render for each identifier
promptManager.render();
promptManager.saveServiceSettings();
return '';
}
export let isExecutingCommandsFromChatInput = false;
export let commandsFromChatInputAbortController;

View File

@@ -0,0 +1,15 @@
<div class="flex-container flexFlowColumn height100p">
<h3 data-i18n="Additional Parameters">Additional Parameters</h3>
<div class="flex1 flex-container flexFlowColumn">
<h4 data-i18n="Include Body Parameters">Include Body Parameters</h4>
<textarea id="custom_include_body" class="flex1" placeholder="Parameters to be included in the Chat Completion request body (YAML object)&#10;&#10;Example:&#10;- top_k: 20&#10;- repetition_penalty: 1.1" data-i18n="[placeholder]custom_include_body_desc"></textarea>
</div>
<div class="flex1 flex-container flexFlowColumn">
<h4 data-i18n="Exclude Body Parameters">Exclude Body Parameters</h4>
<textarea id="custom_exclude_body" class="flex1" placeholder="Parameters to be excluded from the Chat Completion request body (YAML array)&#10;&#10;Example:&#10;- frequency_penalty&#10;- presence_penalty" data-i18n="[placeholder]custom_exclude_body_desc"></textarea>
</div>
<div class="flex1 flex-container flexFlowColumn">
<h4 data-i18n="Include Request Headers">Include Request Headers</h4>
<textarea id="custom_include_headers" class="flex1" placeholder="Additional headers for Chat Completion requests (YAML object)&#10;&#10;Example:&#10;- CustomHeader: custom-value&#10;- AnotherHeader: custom-value" data-i18n="[placeholder]custom_include_headers_desc"></textarea>
</div>
</div>

View File

@@ -1,25 +1,26 @@
Text formatting commands:
<ul>
<li><tt>*text*</tt> - displays as <i>italics</i></li>
<li><tt>**text**</tt> - displays as <b>bold</b></li>
<li><tt>***text***</tt> - displays as <b><i>bold italics</i></b></li>
<li><tt>__text__</tt> - displays as an <u>underline</u></li>
<li><tt>~~text~~</tt> - displays as a <del>strikethough</del></li>
<li><tt>[text](url)</tt> - displays as a <a href="#">hyperlink</a></li>
<li><tt>![text](url)</tt> - displays as an image</li>
<li><tt>```text```</tt> - displays as a code block (new lines allowed between the backticks)</li>
<span data-i18n="help_format_1">Text formatting commands:</span>
<ul> <!-- I know it seems like all these 'display as' could fit into just a couple entries, but other languages might need it with their grammar
Actually I feel that languages with SOV might need even more extra entries, but let's KISS it for now, those can be easily added in the future without breaking anything -->
<li><tt data-i18n="help_format_2">*text*</tt> - <span data-i18n="help_format_3">displays as </span><i data-i18n="help_format_4">italics</i></li>
<li><tt data-i18n="help_format_5">**text**</tt> - <span data-i18n="help_format_6">displays as </span><b data-i18n="help_format_7">bold</b></li>
<li><tt data-i18n="help_format_8">***text***</tt> - <span data-i18n="help_format_9">displays as </span><b><i data-i18n="help_format_10">bold italics</i></b></li>
<li><tt data-i18n="help_format_11">__text__</tt> - <span data-i18n="help_format_12">displays as an </span><u data-i18n="help_format_13">underline</u></li>
<li><tt data-i18n="help_format_14">~~text~~</tt> - <span data-i18n="help_format_15">displays as a </span><del data-i18n="help_format_16">strikethough</del></li>
<li><tt data-i18n="help_format_17">[text](url)</tt> - <span data-i18n="help_format_18">displays as a </span><a href="#" data-i18n="help_format_19">hyperlink</a></li>
<li><tt data-i18n="help_format_20">![text](url)</tt> - <span data-i18n="help_format_21">displays as an image</span></li>
<li><tt data-i18n="help_format_22">```text```</tt> - <span data-i18n="help_format_23">displays as a code block (new lines allowed between the backticks)</span></li>
</ul>
<pre><code> like this</code></pre>
<pre><code data-i18n="help_format_like_this"> like this</code></pre>
<ul>
<li><tt>`text`</tt> - displays as <code>inline code</code></li>
<li><tt>&gt; text</tt> - displays as a blockquote (note the space after &gt;)</li>
<blockquote>like this</blockquote>
<li><tt># text</tt> - displays as a large header (note the space)</li>
<h1>like this</h1>
<li><tt>## text</tt> - displays as a medium header (note the space)</li>
<h2>like this</h2>
<li><tt>### text</tt> - displays as a small header (note the space)</li>
<h3>like this</h3>
<li><tt>$$ text $$</tt> - renders a LaTeX formula (if enabled)</li>
<li><tt>$ text $</tt> - renders an AsciiMath formula (if enabled)</li>
<li><tt data-i18n="help_format_24">`text`</tt> - <span data-i18n="help_format_25">displays as </span><code data-i18n="help_format_26">inline code</code></li>
<li><tt data-i18n="help_format_27">&gt; text</tt> - <span data-i18n="help_format_28">displays as a blockquote (note the space after &gt;)</span></li>
<blockquote data-i18n="help_format_like_this">like this</blockquote>
<li><tt data-i18n="help_format_29"># text</tt> - <span data-i18n="help_format_30">displays as a large header (note the space)</span></li>
<h1 data-i18n="help_format_like_this">like this</h1>
<li><tt data-i18n="help_format_32">## text</tt> - <span data-i18n="help_format_33">displays as a medium header (note the space)</span></li>
<h2 data-i18n="help_format_like_this">like this</h2>
<li><tt data-i18n="help_format_35">### text</tt> - <span data-i18n="help_format_36">displays as a small header (note the space)</span></li>
<h3 data-i18n="help_format_like_this">like this</h3>
<li><tt data-i18n="help_format_38">$$ text $$</tt> - <span data-i18n="help_format_39">renders a LaTeX formula (if enabled)</span></li>
<li><tt data-i18n="help_format_40">$ text $</tt> - <span data-i18n="help_format_41">renders an AsciiMath formula (if enabled)</span></li>
</ul>

View File

@@ -1,11 +1,11 @@
Hello there! Please select the help topic you would like to learn more about:
<span data-i18n="help_1">Hello there! Please select the help topic you would like to learn more about:</span>
<ul>
<li><a href="#" data-displayHelp="1">Slash Commands</a> (or <tt>/help slash</tt>)</li>
<li><a href="#" data-displayHelp="2">Formatting</a> (or <tt>/help format</tt>)</li>
<li><a href="#" data-displayHelp="3">Hotkeys</a> (or <tt>/help hotkeys</tt>)</li>
<li><a href="#" data-displayHelp="4">&lcub;&lcub;Macros&rcub;&rcub;</a> (or <tt>/help macros</tt>)</li>
<li><a href="#" data-displayHelp="1" data-i18n="help_2">Slash Commands</a> (<span data-i18n="help_or">or</span> <tt>/help slash</tt>)</li>
<li><a href="#" data-displayHelp="2" data-i18n="help_3">Formatting</a> (<span data-i18n="help_or">or</span> <tt>/help format</tt>)</li>
<li><a href="#" data-displayHelp="3" data-i18n="help_4">Hotkeys</a> (<span data-i18n="help_or">or</span> <tt>/help hotkeys</tt>)</li>
<li><a href="#" data-displayHelp="4" data-i18n="help_5">&lcub;&lcub;Macros&rcub;&rcub;</a> (<span data-i18n="help_or">or</span> <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!
<span data-i18n="help_6">Still got questions left? The</span> <a target="_blank" href="https://docs.sillytavern.app/" data-i18n="help_7">Official SillyTavern Documentation Website</a><span data-i18n="help_8"> has much more information!</span>
</b>

View File

@@ -1,13 +1,13 @@
Hotkeys/Keybinds:
<span data-i18n="help_hotkeys_0">Hotkeys/Keybinds</span>:
<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>Enter</tt> (with chat bar selected) = send your message to AI</li>
<li><tt>Ctrl+Enter</tt> = Regenerate the last AI response</li>
<li><tt>Alt+Enter</tt> = Continue the last AI response</li>
<li><tt>Escape</tt> = stop AI response generation, close UI panels, cancel message edit</li>
<li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li>
<li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li>
<li><tt data-i18n="help_hotkeys_1">Up</tt> = <span data-i18n="help_hotkeys_2">Edit last message in chat</span></li>
<li><tt data-i18n="help_hotkeys_3">Ctrl+Up</tt> = <span data-i18n="help_hotkeys_4">Edit last USER message in chat</span></li>
<li><tt data-i18n="help_hotkeys_5">Left</tt> = <span data-i18n="help_hotkeys_6">swipe left</span></li>
<li><tt data-i18n="help_hotkeys_7">Right</tt> = <span data-i18n="help_hotkeys_8">swipe right (NOTE: swipe hotkeys are disabled when chatbar has something typed into it)</span></li>
<li><tt data-i18n="help_hotkeys_9">Enter</tt> <span data-i18n="help_hotkeys_10">(with chat bar selected)</span> = <span data-i18n="help_hotkeys_10_1">send your message to AI</span></li>
<li><tt data-i18n="help_hotkeys_11">Ctrl+Enter</tt> = <span data-i18n="help_hotkeys_12">Regenerate the last AI response</span></li>
<li><tt data-i18n="help_hotkeys_13">Alt+Enter</tt> = <span data-i18n="help_hotkeys_14">Continue the last AI response</span></li>
<li><tt data-i18n="help_hotkeys_15">Escape</tt> = <span data-i18n="help_hotkeys_16">stop AI response generation, close UI panels, cancel message edit</span></li>
<li><tt data-i18n="help_hotkeys_17">Ctrl+Shift+Up</tt> = <span data-i18n="help_hotkeys_18">Scroll to context line</span></li>
<li><tt data-i18n="help_hotkeys_19">Ctrl+Shift+Down</tt> = <span data-i18n="help_hotkeys_20">Scroll chat to bottom</span></li>
</ul>

View File

@@ -1,91 +1,91 @@
<div>
<div data-i18n="System-wide Replacement Macros (in order of evaluation):">
System-wide Replacement Macros (in order of evaluation):
</div>
<ul>
<li><tt>&lcub;&lcub;pipe&rcub;&rcub;</tt> only for slash command batching. Replaced with the returned result of the previous command.</li>
<li><tt>&lcub;&lcub;newline&rcub;&rcub;</tt> just inserts a newline.</li>
<li><tt>&lcub;&lcub;trim&rcub;&rcub;</tt> trims newlines surrounding this macro.</li>
<li><tt>&lcub;&lcub;noop&rcub;&rcub;</tt> no operation, just an empty string.</li>
<li><tt>&lcub;&lcub;original&rcub;&rcub;</tt> global prompts defined in API settings. Only valid in Advanced Definitions prompt overrides.</li>
<li><tt>&lcub;&lcub;input&rcub;&rcub;</tt> the user input</li>
<li><tt>&lcub;&lcub;charPrompt&rcub;&rcub;</tt> the Character's Main Prompt override</li>
<li><tt>&lcub;&lcub;charJailbreak&rcub;&rcub;</tt> the Character's Jailbreak Prompt override</li>
<li><tt>&lcub;&lcub;description&rcub;&rcub;</tt> the Character's Description</li>
<li><tt>&lcub;&lcub;personality&rcub;&rcub;</tt> the Character's Personality</li>
<li><tt>&lcub;&lcub;scenario&rcub;&rcub;</tt> the Character's Scenario</li>
<li><tt>&lcub;&lcub;persona&rcub;&rcub;</tt> your current Persona Description</li>
<li><tt>&lcub;&lcub;mesExamples&rcub;&rcub;</tt> the Character's Dialogue Examples</li>
<li><tt>&lcub;&lcub;mesExamplesRaw&rcub;&rcub;</tt> unformatted Dialogue Examples <b>(only for Story String)</b></li>
<li><tt>&lcub;&lcub;user&rcub;&rcub;</tt> your current Persona username</li>
<li><tt>&lcub;&lcub;char&rcub;&rcub;</tt> the Character's name</li>
<li><tt>&lcub;&lcub;char_version&rcub;&rcub;</tt> the Character's version number</li>
<li><tt>&lcub;&lcub;group&rcub;&rcub;</tt> a comma-separated list of group member names or the character name in solo chats. Alias: &lcub;&lcub;charIfNotGroup&rcub;&rcub;</li>
<li><tt>&lcub;&lcub;model&rcub;&rcub;</tt> a text generation model name for the currently selected API. <b>Can be inaccurate!</b></li>
<li><tt>&lcub;&lcub;lastMessage&rcub;&rcub;</tt> - the text of the latest chat message.</li>
<li><tt>&lcub;&lcub;lastMessageId&rcub;&rcub;</tt> index # of the latest chat message. Useful for slash command batching.</li>
<li><tt>&lcub;&lcub;firstIncludedMessageId&rcub;&rcub;</tt> - the ID of the first message included in the context. Requires generation to be ran at least once in the current session.</li>
<li><tt>&lcub;&lcub;currentSwipeId&rcub;&rcub;</tt> the 1-based ID of the current swipe in the last chat message. Empty string if the last message is user or prompt-hidden.</li>
<li><tt>&lcub;&lcub;lastSwipeId&rcub;&rcub;</tt> the number of swipes in the last chat message. Empty string if the last message is user or prompt-hidden.</li>
<li><tt>&lcub;&lcub;// (note)&rcub;&rcub;</tt> you can leave a note here, and the macro will be replaced with blank content. Not visible for the AI.</li>
<li><tt>&lcub;&lcub;time&rcub;&rcub;</tt> the current time</li>
<li><tt>&lcub;&lcub;date&rcub;&rcub;</tt> the current date</li>
<li><tt>&lcub;&lcub;weekday&rcub;&rcub;</tt> the current weekday</li>
<li><tt>&lcub;&lcub;isotime&rcub;&rcub;</tt> the current ISO time (24-hour clock)</li>
<li><tt>&lcub;&lcub;isodate&rcub;&rcub;</tt> the current ISO date (YYYY-MM-DD)</li>
<li><tt>&lcub;&lcub;datetimeformat &hellip;&rcub;&rcub;</tt> the current date/time in the specified format, e. g. for German date/time: <tt>&lcub;&lcub;datetimeformat DD.MM.YYYY HH:mm&rcub;&rcub;</tt></li>
<li><tt>&lcub;&lcub;time_UTC±#&rcub;&rcub;</tt> the current time in the specified UTC time zone offset, e.g. UTC-4 or UTC+2</li>
<li><tt>&lcub;&lcub;timeDiff::(time1)::(time2)&rcub;&rcub;</tt> the time difference between time1 and time2. Accepts time and date macros. (Ex: &lcub;&lcub;timeDiff::&lcub;&lcub;isodate&rcub;&rcub; &lcub;&lcub;time&rcub;&rcub;::2024/5/11 12:30:00&rcub;&rcub;)</li>
<li><tt>&lcub;&lcub;idle_duration&rcub;&rcub;</tt> the time since the last user message was sent</li>
<li><tt>&lcub;&lcub;bias "text here"&rcub;&rcub;</tt> sets a behavioral bias for the AI until the next user input. Quotes around the text are important.</li>
<li><tt>&lcub;&lcub;roll:(formula)&rcub;&rcub;</tt> rolls a dice. (ex: <tt>>&lcub;&lcub;roll:1d6&rcub;&rcub;</tt> will roll a 6-sided dice and return a number between 1 and 6)</li>
<li><tt>&lcub;&lcub;random:(args)&rcub;&rcub;</tt> returns a random item from the list. (ex: <tt>&lcub;&lcub;random:1,2,3,4&rcub;&rcub;</tt> will return 1 of the 4 numbers at random. Works with text lists too.</li>
<li><tt>&lcub;&lcub;random::(arg1)::(arg2)&rcub;&rcub;</tt> alternative syntax for random that allows to use commas in the list items.</li>
<li><tt>&lcub;&lcub;pick::(args)&rcub;&rcub;</tt> picks a random item from the list. Works the same as &lcub;&lcub;random&rcub;&rcub;, with the same possible syntax options, but the pick will stay consistent for this chat once picked and won't be re-rolled on consecutive messages and prompt processing.</li>
<li><tt>&lcub;&lcub;banned "text here"&rcub;&rcub;</tt> dynamically add text in the quotes to banned words sequences, if Text Generation WebUI backend used. Do nothing for others backends. Can be used anywhere (Character description, WI, AN, etc.) Quotes around the text are important.</li>
<li><tt>&lcub;&lcub;pipe&rcub;&rcub;</tt> <span data-i18n="help_macros_1">only for slash command batching. Replaced with the returned result of the previous command.</span></li>
<li><tt>&lcub;&lcub;newline&rcub;&rcub;</tt> <span data-i18n="help_macros_2">just inserts a newline.</span></li>
<li><tt>&lcub;&lcub;trim&rcub;&rcub;</tt> <span data-i18n="help_macros_3">trims newlines surrounding this macro.</span></li>
<li><tt>&lcub;&lcub;noop&rcub;&rcub;</tt> <span data-i18n="help_macros_4">no operation, just an empty string.</span></li>
<li><tt>&lcub;&lcub;original&rcub;&rcub;</tt> <span data-i18n="help_macros_5">global prompts defined in API settings. Only valid in Advanced Definitions prompt overrides.</span></li>
<li><tt>&lcub;&lcub;input&rcub;&rcub;</tt> <span data-i18n="help_macros_6">the user input</span></li>
<li><tt>&lcub;&lcub;charPrompt&rcub;&rcub;</tt> <span data-i18n="help_macros_7">the Character's Main Prompt override</span></li>
<li><tt>&lcub;&lcub;charJailbreak&rcub;&rcub;</tt> <span data-i18n="help_macros_8">the Character's Jailbreak Prompt override</span></li>
<li><tt>&lcub;&lcub;description&rcub;&rcub;</tt> <span data-i18n="help_macros_9">the Character's Description</span></li>
<li><tt>&lcub;&lcub;personality&rcub;&rcub;</tt> <span data-i18n="help_macros_10">the Character's Personality</span></li>
<li><tt>&lcub;&lcub;scenario&rcub;&rcub;</tt> <span data-i18n="help_macros_11">the Character's Scenario</span></li>
<li><tt>&lcub;&lcub;persona&rcub;&rcub;</tt> <span data-i18n="help_macros_12">your current Persona Description</span></li>
<li><tt>&lcub;&lcub;mesExamples&rcub;&rcub;</tt> <span data-i18n="help_macros_13">the Character's Dialogue Examples</span></li>
<li><tt>&lcub;&lcub;mesExamplesRaw&rcub;&rcub;</tt> <span data-i18n="help_macros_14">unformatted Dialogue Examples </span><b data-i18n="(only for Story String)">(only for Story String)</b></li>
<li><tt>&lcub;&lcub;user&rcub;&rcub;</tt> <span data-i18n="help_macros_15">your current Persona username</span></li>
<li><tt>&lcub;&lcub;char&rcub;&rcub;</tt> <span data-i18n="help_macros_16">the Character's name</span></li>
<li><tt>&lcub;&lcub;char_version&rcub;&rcub;</tt> <span data-i18n="help_macros_17">the Character's version number</span></li>
<li><tt>&lcub;&lcub;group&rcub;&rcub;</tt> <span data-i18n="help_macros_18">a comma-separated list of group member names or the character name in solo chats. Alias: &lcub;&lcub;charIfNotGroup&rcub;&rcub;</span></li>
<li><tt>&lcub;&lcub;model&rcub;&rcub;</tt> <span data-i18n="help_macros_19">a text generation model name for the currently selected API. </span><b data-i18n="Can be inaccurate!">Can be inaccurate!</b></li>
<li><tt>&lcub;&lcub;lastMessage&rcub;&rcub;</tt> - <span data-i18n="help_macros_20">the text of the latest chat message.</span></li>
<li><tt>&lcub;&lcub;lastMessageId&rcub;&rcub;</tt> <span data-i18n="help_macros_21">index # of the latest chat message. Useful for slash command batching.</span></li>
<li><tt>&lcub;&lcub;firstIncludedMessageId&rcub;&rcub;</tt> - <span data-i18n="help_macros_22">the ID of the first message included in the context. Requires generation to be ran at least once in the current session.</span></li>
<li><tt>&lcub;&lcub;currentSwipeId&rcub;&rcub;</tt> <span data-i18n="help_macros_23">the 1-based ID of the current swipe in the last chat message. Empty string if the last message is user or prompt-hidden.</span></li>
<li><tt>&lcub;&lcub;lastSwipeId&rcub;&rcub;</tt> <span data-i18n="help_macros_24">the number of swipes in the last chat message. Empty string if the last message is user or prompt-hidden.</span></li>
<li><tt>&lcub;&lcub;// (note)&rcub;&rcub;</tt> <span data-i18n="help_macros_25">you can leave a note here, and the macro will be replaced with blank content. Not visible for the AI.</span></li>
<li><tt>&lcub;&lcub;time&rcub;&rcub;</tt> <span data-i18n="help_macros_26">the current time</span></li>
<li><tt>&lcub;&lcub;date&rcub;&rcub;</tt> <span data-i18n="help_macros_27">the current date</span></li>
<li><tt>&lcub;&lcub;weekday&rcub;&rcub;</tt> <span data-i18n="help_macros_28">the current weekday</span></li>
<li><tt>&lcub;&lcub;isotime&rcub;&rcub;</tt> <span data-i18n="help_macros_29">the current ISO time (24-hour clock)</span></li>
<li><tt>&lcub;&lcub;isodate&rcub;&rcub;</tt> <span data-i18n="help_macros_30">the current ISO date (YYYY-MM-DD)</span></li>
<li><tt>&lcub;&lcub;datetimeformat &hellip;&rcub;&rcub;</tt> <span data-i18n="help_macros_31">the current date/time in the specified format, e. g. for German date/time: </span><tt>&lcub;&lcub;datetimeformat DD.MM.YYYY HH:mm&rcub;&rcub;</tt></li>
<li><tt>&lcub;&lcub;time_UTC±#&rcub;&rcub;</tt> <span data-i18n="help_macros_32">the current time in the specified UTC time zone offset, e.g. UTC-4 or UTC+2</span></li>
<li><tt>&lcub;&lcub;timeDiff::(time1)::(time2)&rcub;&rcub;</tt> <span data-i18n="help_macros_33">the time difference between time1 and time2. Accepts time and date macros. (Ex: &lcub;&lcub;timeDiff::&lcub;&lcub;isodate&rcub;&rcub; &lcub;&lcub;time&rcub;&rcub;::2024/5/11 12:30:00&rcub;&rcub;)</span></li>
<li><tt>&lcub;&lcub;idle_duration&rcub;&rcub;</tt> <span data-i18n="help_macros_34">the time since the last user message was sent</span></li>
<li><tt>&lcub;&lcub;bias "text here"&rcub;&rcub;</tt> <span data-i18n="help_macros_35">sets a behavioral bias for the AI until the next user input. Quotes around the text are important.</span></li>
<li><tt>&lcub;&lcub;roll:(formula)&rcub;&rcub;</tt> <span data-i18n="help_macros_36">rolls a dice. (ex: </span><tt>&lcub;&lcub;roll:1d6&rcub;&rcub;</tt><span data-i18n="space_ will roll a 6-sided dice and return a number between 1 and 6)"> will roll a 6-sided dice and return a number between 1 and 6)</span></li>
<li><tt>&lcub;&lcub;random:(args)&rcub;&rcub;</tt> <span data-i18n="help_macros_37">returns a random item from the list. (ex: </span><tt>&lcub;&lcub;random:1,2,3,4&rcub;&rcub;</tt><span data-i18n="space_ will return 1 of the 4 numbers at random. Works with text lists too."> will return 1 of the 4 numbers at random. Works with text lists too.</span></li>
<li><tt>&lcub;&lcub;random::(arg1)::(arg2)&rcub;&rcub;</tt> <span data-i18n="help_macros_38">alternative syntax for random that allows to use commas in the list items.</span></li>
<li><tt>&lcub;&lcub;pick::(args)&rcub;&rcub;</tt> <span data-i18n="help_macros_39">picks a random item from the list. Works the same as &lcub;&lcub;random&rcub;&rcub;, with the same possible syntax options, but the pick will stay consistent for this chat once picked and won't be re-rolled on consecutive messages and prompt processing.</span></li>
<li><tt>&lcub;&lcub;banned "text here"&rcub;&rcub;</tt> <span data-i18n="help_macros_40">dynamically add text in the quotes to banned words sequences, if Text Generation WebUI backend used. Do nothing for others backends. Can be used anywhere (Character description, WI, AN, etc.) Quotes around the text are important.</span></li>
</ul>
<div>
<div data-i18n="Instruct Mode and Context Template Macros:">
Instruct Mode and Context Template Macros:
</div>
<div>
<small>(enabled in the Advanced Formatting settings)</small>
<small data-i18n="(enabled in the Advanced Formatting settings)">(enabled in the Advanced Formatting settings)</small>
</div>
<ul>
<li><tt>&lcub;&lcub;maxPrompt&rcub;&rcub;</tt> max allowed prompt length in tokens = (context size - response length)</li>
<li><tt>&lcub;&lcub;exampleSeparator&rcub;&rcub;</tt> context template example dialogues separator</li>
<li><tt>&lcub;&lcub;chatStart&rcub;&rcub;</tt> context template chat start line</li>
<li><tt>&lcub;&lcub;systemPrompt&rcub;&rcub;</tt> main system prompt (either character prompt override if chosen, or instructSystemPrompt)</li>
<li><tt>&lcub;&lcub;instructSystemPrompt&rcub;&rcub;</tt> instruct system prompt</li>
<li><tt>&lcub;&lcub;instructSystemPromptPrefix&rcub;&rcub;</tt> instruct system prompt prefix sequence</li>
<li><tt>&lcub;&lcub;instructSystemPromptSuffix&rcub;&rcub;</tt> instruct system prompt suffix sequence</li>
<li><tt>&lcub;&lcub;instructUserPrefix&rcub;&rcub;</tt> instruct user prefix sequence</li>
<li><tt>&lcub;&lcub;instructUserSuffix&rcub;&rcub;</tt> instruct user suffix sequence</li>
<li><tt>&lcub;&lcub;instructAssistantPrefix&rcub;&rcub;</tt> instruct assistant prefix sequence</li>
<li><tt>&lcub;&lcub;instructAssistantSuffix&rcub;&rcub;</tt> instruct assistant suffix sequence</li>
<li><tt>&lcub;&lcub;instructFirstAssistantPrefix&rcub;&rcub;</tt> instruct assistant first output sequence</li>
<li><tt>&lcub;&lcub;instructLastAssistantPrefix&rcub;&rcub;</tt> instruct assistant last output sequence</li>
<li><tt>&lcub;&lcub;instructSystemPrefix&rcub;&rcub;</tt> instruct system message prefix sequence</li>
<li><tt>&lcub;&lcub;instructSystemSuffix&rcub;&rcub;</tt> instruct system message suffix sequence</li>
<li><tt>&lcub;&lcub;instructSystemInstructionPrefix&rcub;&rcub;</tt> instruct system instruction prefix</li>
<li><tt>&lcub;&lcub;instructUserFiller&rcub;&rcub;</tt> instruct first user message filler</li>
<li><tt>&lcub;&lcub;instructStop&rcub;&rcub;</tt> instruct stop sequence</li>
<li><tt>&lcub;&lcub;maxPrompt&rcub;&rcub;</tt> <span data-i18n="help_macros_41">max allowed prompt length in tokens = (context size - response length)</span></li>
<li><tt>&lcub;&lcub;exampleSeparator&rcub;&rcub;</tt> <span data-i18n="help_macros_42">context template example dialogues separator</span></li>
<li><tt>&lcub;&lcub;chatStart&rcub;&rcub;</tt> <span data-i18n="help_macros_43">context template chat start line</span></li>
<li><tt>&lcub;&lcub;systemPrompt&rcub;&rcub;</tt> <span data-i18n="help_macros_44">main system prompt (either character prompt override if chosen, or instructSystemPrompt)</span></li>
<li><tt>&lcub;&lcub;instructSystemPrompt&rcub;&rcub;</tt> <span data-i18n="help_macros_45">instruct system prompt</span></li>
<li><tt>&lcub;&lcub;instructSystemPromptPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_46">instruct system prompt prefix sequence</span></li>
<li><tt>&lcub;&lcub;instructSystemPromptSuffix&rcub;&rcub;</tt> <span data-i18n="help_macros_47">instruct system prompt suffix sequence</span></li>
<li><tt>&lcub;&lcub;instructUserPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_48">instruct user prefix sequence</span></li>
<li><tt>&lcub;&lcub;instructUserSuffix&rcub;&rcub;</tt> <span data-i18n="help_macros_49">instruct user suffix sequence</span></li>
<li><tt>&lcub;&lcub;instructAssistantPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_50">instruct assistant prefix sequence</span></li>
<li><tt>&lcub;&lcub;instructAssistantSuffix&rcub;&rcub;</tt> <span data-i18n="help_macros_51">instruct assistant suffix sequence</span></li>
<li><tt>&lcub;&lcub;instructFirstAssistantPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_52">instruct assistant first output sequence</span></li>
<li><tt>&lcub;&lcub;instructLastAssistantPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_53">instruct assistant last output sequence</span></li>
<li><tt>&lcub;&lcub;instructSystemPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_54">instruct system message prefix sequence</span></li>
<li><tt>&lcub;&lcub;instructSystemSuffix&rcub;&rcub;</tt> <span data-i18n="help_macros_55">instruct system message suffix sequence</span></li>
<li><tt>&lcub;&lcub;instructSystemInstructionPrefix&rcub;&rcub;</tt> <span data-i18n="help_macros_56">instruct system instruction prefix</span></li>
<li><tt>&lcub;&lcub;instructUserFiller&rcub;&rcub;</tt> <span data-i18n="help_macros_57">instruct first user message filler</span></li>
<li><tt>&lcub;&lcub;instructStop&rcub;&rcub;</tt> <span data-i18n="help_macros_58">instruct stop sequence</span></li>
</ul>
<div>
<div data-i18n="Chat variables Macros:">
Chat variables Macros:
</div>
<div><small>Local variables = unique to the current chat</small></div>
<div><small>Global variables = works in any chat for any character</small></div>
<div><small>Scoped variables = works in STscript</small></div>
<div><small data-i18n="Local variables = unique to the current chat">Local variables = unique to the current chat</small></div>
<div><small data-i18n="Global variables = works in any chat for any character">Global variables = works in any chat for any character</small></div>
<div><small data-i18n="Scoped variables = works in STscript">Scoped variables = works in STscript</small></div>
<ul>
<li><tt>&lcub;&lcub;getvar::name&rcub;&rcub;</tt> replaced with the value of the local variable "name"</li>
<li><tt>&lcub;&lcub;setvar::name::value&rcub;&rcub;</tt> replaced with empty string, sets the local variable "name" to "value"</li>
<li><tt>&lcub;&lcub;addvar::name::increment&rcub;&rcub;</tt> replaced with empty strings, adds a numeric value of "increment" to the local variable "name"</li>
<li><tt>&lcub;&lcub;incvar::name&rcub;&rcub;</tt> replaced with the result of the increment of value of the variable "name" by 1</li>
<li><tt>&lcub;&lcub;decvar::name&rcub;&rcub;</tt> replaced with the result of the decrement of value of the variable "name" by 1</li>
<li><tt>&lcub;&lcub;getglobalvar::name&rcub;&rcub;</tt> replaced with the value of the global variable "name"</li>
<li><tt>&lcub;&lcub;setglobalvar::name::value&rcub;&rcub;</tt> replaced with empty string, sets the global variable "name" to "value"</li>
<li><tt>&lcub;&lcub;addglobalvar::name::value&rcub;&rcub;</tt> replaced with empty string, adds a numeric value of "increment" to the global variable "name"</li>
<li><tt>&lcub;&lcub;incglobalvar::name&rcub;&rcub;</tt> replaced with the result of the increment of value of the global variable "name" by 1</li>
<li><tt>&lcub;&lcub;decglobalvar::name&rcub;&rcub;</tt> replaced with the result of the decrement of value of the global variable "name" by 1</li>
<li><tt>&lcub;&lcub;var::name&rcub;&rcub;</tt> replaced with the value of the scoped variable "name"</li>
<li><tt>&lcub;&lcub;var::name::index&rcub;&rcub;</tt> replaced with the value of item at index (for arrays / lists or objects / dictionaries) of the scoped variable "name"</li>
<li><tt>&lcub;&lcub;getvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_59">replaced with the value of the local variable "name"</span></li>
<li><tt>&lcub;&lcub;setvar::name::value&rcub;&rcub;</tt> <span data-i18n="help_macros_60">replaced with empty string, sets the local variable "name" to "value"</span></li>
<li><tt>&lcub;&lcub;addvar::name::increment&rcub;&rcub;</tt> <span data-i18n="help_macros_61">replaced with empty strings, adds a numeric value of "increment" to the local variable "name"</span></li>
<li><tt>&lcub;&lcub;incvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_62">replaced with the result of the increment of value of the variable "name" by 1</span></li>
<li><tt>&lcub;&lcub;decvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_63">replaced with the result of the decrement of value of the variable "name" by 1</span></li>
<li><tt>&lcub;&lcub;getglobalvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_64">replaced with the value of the global variable "name"</span></li>
<li><tt>&lcub;&lcub;setglobalvar::name::value&rcub;&rcub;</tt> <span data-i18n="help_macros_65">replaced with empty string, sets the global variable "name" to "value"</span></li>
<li><tt>&lcub;&lcub;addglobalvar::name::value&rcub;&rcub;</tt> <span data-i18n="help_macros_66">replaced with empty string, adds a numeric value of "increment" to the global variable "name"</span></li>
<li><tt>&lcub;&lcub;incglobalvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_67">replaced with the result of the increment of value of the global variable "name" by 1</span></li>
<li><tt>&lcub;&lcub;decglobalvar::name&rcub;&rcub;</tt> <span data-i18n="help_macros_68">replaced with the result of the decrement of value of the global variable "name" by 1</span></li>
<li><tt>&lcub;&lcub;var::name&rcub;&rcub;</tt> <span data-i18n="help_macros_69">replaced with the value of the scoped variable "name"</span></li>
<li><tt>&lcub;&lcub;var::name::index&rcub;&rcub;</tt> <span data-i18n="help_macros_70">replaced with the value of item at index (for arrays / lists or objects / dictionaries) of the scoped variable "name"</span></li>
</ul>

View File

@@ -8,10 +8,10 @@
<h3 data-i18n="How to start chatting?">How to start chatting?</h3>
<ol>
<li>
<span data-i18n="Click ">Click </span><code><i class="fa-solid fa-plug"></i></code><span data-i18n="and select a"> and select a </span><a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank" data-i18n="Chat API">Chat API</a>.</span>
<span data-i18n="Click _space">Click </span><code><i class="fa-solid fa-plug"></i></code><span data-i18n="and select a"> and select a </span><a href="https://docs.sillytavern.app/usage/api-connections/" target="_blank" data-i18n="Chat API">Chat API</a>.</span>
</li>
<li>
<span data-i18n="Click ">Click </span><code><i class="fa-solid fa-address-card"></i></code><span data-i18n="and pick a character."> and pick a character.</span>
<span data-i18n="Click _space">Click </span><code><i class="fa-solid fa-address-card"></i></code><span data-i18n="and pick a character."> and pick a character.</span>
</li>
</ol>
<div>

View File

@@ -292,6 +292,9 @@ export function throttle(func, limit = 300) {
* @returns {boolean} True if the element is in the viewport, false otherwise.
*/
export function isElementInViewport(el) {
if (!el) {
return false;
}
if (typeof jQuery === 'function' && el instanceof jQuery) {
el = el[0];
}