mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' of https://github.com/BlipRanger/SillyTavern into dev
This commit is contained in:
@@ -115,7 +115,7 @@
|
||||
Click slider numbers to input manually.
|
||||
</div>
|
||||
<div class="scrollableInner">
|
||||
<div class="flex-container">
|
||||
<div class="flex-container" id="ai_response_configuration">
|
||||
<div id="respective-presets-block" class="width100p">
|
||||
<div id="kobold_api-presets">
|
||||
<h3><span data-i18n="kobldpresets">Kobold Presets</span>
|
||||
@@ -178,7 +178,7 @@
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="amount_gen" name="volume" min="16" max="1024" step="1">
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div class="range-block-counter" data-randomization-disabled="true">
|
||||
<div contenteditable="true" data-for="amount_gen" id="amount_gen_counter">
|
||||
select
|
||||
</div>
|
||||
@@ -194,7 +194,7 @@
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="max_context" name="volume" min="512" max="2048" step="1">
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div class="range-block-counter" data-randomization-disabled="true">
|
||||
<div contenteditable="true" data-for="max_context" id="max_context_counter">
|
||||
select
|
||||
</div>
|
||||
@@ -535,7 +535,7 @@
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="openai_max_context" name="volume" min="512" max="4095" step="1">
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div class="range-block-counter" data-randomization-disabled="true">
|
||||
<div contenteditable="true" data-for="openai_max_context" id="openai_max_context_counter">
|
||||
select
|
||||
</div>
|
||||
|
@@ -433,6 +433,7 @@ const system_messages = {
|
||||
<ul>
|
||||
<li><tt>{{user}}</tt> - your current Persona username</li>
|
||||
<li><tt>{{char}}</tt> - the Character's name</li>
|
||||
<li><tt>{{input}}</tt> - the user input</li>
|
||||
<li><tt>{{time}}</tt> - the current time</li>
|
||||
<li><tt>{{date}}</tt> - the current date</li>
|
||||
<li><tt>{{idle_duration}}</tt> - the time since the last user message was sent</li>
|
||||
@@ -445,6 +446,7 @@ const system_messages = {
|
||||
name: systemUserName,
|
||||
force_avatar: system_avatar,
|
||||
is_user: false,
|
||||
is_system: true,
|
||||
is_name: true,
|
||||
mes: [
|
||||
'<h3><span id="version_display_welcome">SillyTavern</span><div id="version_display_welcome"></div></h3>',
|
||||
@@ -1138,7 +1140,20 @@ function messageFormatting(mes, ch_name, isSystem, isUser) {
|
||||
mes = mes.replaceAll(substituteParams(power_user.user_prompt_bias), "");
|
||||
}
|
||||
|
||||
mes = getRegexedString(mes, regex_placement.MD_DISPLAY);
|
||||
if (!isSystem) {
|
||||
let regexPlacement;
|
||||
if (isUser) {
|
||||
regexPlacement = regex_placement.USER_INPUT;
|
||||
} else if (ch_name === "System") {
|
||||
regexPlacement = regex_placement.SYSTEM;
|
||||
} else if (ch_name !== name2) {
|
||||
regexPlacement = regex_placement.SENDAS;
|
||||
} else {
|
||||
regexPlacement = regex_placement.AI_OUTPUT;
|
||||
}
|
||||
|
||||
mes = getRegexedString(mes, regexPlacement, { isMarkdown: true });
|
||||
}
|
||||
|
||||
if (power_user.auto_fix_generated_markdown) {
|
||||
mes = fixMarkdown(mes);
|
||||
@@ -1513,6 +1528,7 @@ function substituteParams(content, _name1, _name2, _original) {
|
||||
content = content.replace(/{{original}}/i, _original);
|
||||
}
|
||||
|
||||
content = content.replace(/{{input}}/gi, $('#send_textarea').val());
|
||||
content = content.replace(/{{user}}/gi, _name1);
|
||||
content = content.replace(/{{char}}/gi, _name2);
|
||||
content = content.replace(/<USER>/gi, _name1);
|
||||
|
@@ -63,6 +63,11 @@ const extension_settings = {
|
||||
translate: {},
|
||||
objective: {},
|
||||
quickReply: {},
|
||||
randomizer: {
|
||||
controls: [],
|
||||
fluctuation: 0.1,
|
||||
enabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
let modules = [];
|
||||
|
152
public/scripts/extensions/randomize/index.js
Normal file
152
public/scripts/extensions/randomize/index.js
Normal file
@@ -0,0 +1,152 @@
|
||||
import { saveSettingsDebounced } from "../../../script.js";
|
||||
import { extension_settings } from "../../extensions.js";
|
||||
|
||||
function toggleRandomizedSetting(buttonRef, forId) {
|
||||
if (extension_settings.randomizer.controls.indexOf(forId) === -1) {
|
||||
extension_settings.randomizer.controls.push(forId);
|
||||
} else {
|
||||
extension_settings.randomizer.controls = extension_settings.randomizer.controls.filter(x => x !== forId);
|
||||
}
|
||||
|
||||
buttonRef.toggleClass('active');
|
||||
console.debug('Randomizer controls:', extension_settings.randomizer.controls);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
function addRandomizeButton() {
|
||||
const counterRef = $(this);
|
||||
const labelRef = $(this).find('div[data-for]');
|
||||
const isDisabled = counterRef.data('randomization-disabled');
|
||||
|
||||
if (labelRef.length === 0 || isDisabled == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const forId = labelRef.data('for');
|
||||
const buttonRef = $('<div class="randomize_button menu_button fa-solid fa-shuffle"></div>');
|
||||
buttonRef.toggleClass('active', extension_settings.randomizer.controls.indexOf(forId) !== -1);
|
||||
buttonRef.hide();
|
||||
buttonRef.on('click', () => toggleRandomizedSetting(buttonRef, forId));
|
||||
counterRef.append(buttonRef);
|
||||
}
|
||||
|
||||
function onRandomizerEnabled() {
|
||||
extension_settings.randomizer.enabled = $(this).prop('checked');
|
||||
$('.randomize_button').toggle(extension_settings.randomizer.enabled);
|
||||
console.debug('Randomizer enabled:', extension_settings.randomizer.enabled);
|
||||
}
|
||||
|
||||
window['randomizerInterceptor'] = (function () {
|
||||
if (extension_settings.randomizer.enabled === false) {
|
||||
console.debug('Randomizer skipped: disabled.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (extension_settings.randomizer.fluctuation === 0 || extension_settings.randomizer.controls.length === 0) {
|
||||
console.debug('Randomizer skipped: nothing to do.');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const control of extension_settings.randomizer.controls) {
|
||||
const controlRef = $('#' + control);
|
||||
|
||||
if (controlRef.length === 0) {
|
||||
console.debug(`Randomizer skipped: control ${control} not found.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!controlRef.is(':visible')) {
|
||||
console.debug(`Randomizer skipped: control ${control} is not visible.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let previousValue = parseFloat(controlRef.data('previous-value'));
|
||||
let originalValue = parseFloat(controlRef.data('original-value'));
|
||||
let currentValue = parseFloat(controlRef.val());
|
||||
|
||||
let value;
|
||||
|
||||
// Initialize originalValue and previousValue if they are NaN
|
||||
if (isNaN(originalValue)) {
|
||||
originalValue = currentValue;
|
||||
controlRef.data('original-value', originalValue);
|
||||
}
|
||||
if (isNaN(previousValue)) {
|
||||
previousValue = currentValue;
|
||||
controlRef.data('previous-value', previousValue);
|
||||
}
|
||||
|
||||
// If the current value hasn't changed compared to the previous value, use the original value as a base for the calculation
|
||||
if (currentValue === previousValue) {
|
||||
console.debug(`Randomizer for ${control} reusing original value: ${originalValue}`);
|
||||
value = originalValue;
|
||||
} else {
|
||||
console.debug(`Randomizer for ${control} using current value: ${currentValue}`);
|
||||
value = currentValue;
|
||||
controlRef.data('previous-value', currentValue); // Update the previous value when using the current value
|
||||
controlRef.data('original-value', currentValue); // Update the original value when using the current value
|
||||
}
|
||||
|
||||
if (isNaN(value)) {
|
||||
console.debug('Randomizer skipped: NaN.');
|
||||
continue;
|
||||
}
|
||||
|
||||
const fluctuation = extension_settings.randomizer.fluctuation;
|
||||
const min = parseFloat(controlRef.attr('min'));
|
||||
const max = parseFloat(controlRef.attr('max'));
|
||||
const delta = (Math.random() * fluctuation * 2 - fluctuation) * value;
|
||||
const newValue = Math.min(Math.max(value + delta, min), max);
|
||||
console.debug(`Randomizer for ${control}: ${value} -> ${newValue} (delta: ${delta}, min: ${min}, max: ${max})`);
|
||||
controlRef.val(newValue).trigger('input');
|
||||
controlRef.data('previous-value', parseFloat(controlRef.val()));
|
||||
}
|
||||
});
|
||||
|
||||
jQuery(() => {
|
||||
const html = `
|
||||
<div class="randomizer_settings">
|
||||
<div class="inline-drawer">
|
||||
<div class="inline-drawer-toggle inline-drawer-header">
|
||||
<b>Parameter Randomizer</b>
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<label for="randomizer_enabled" class="checkbox_label">
|
||||
<input type="checkbox" id="randomizer_enabled" name="randomizer_enabled" >
|
||||
Enabled
|
||||
</label>
|
||||
<div class="range-block">
|
||||
<div class="range-block-title">
|
||||
Fluctuation (0-1)
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range-and-counter">
|
||||
<div class="range-block-range">
|
||||
<input type="range" id="randomizer_fluctuation" min="0" max="1" step="0.1">
|
||||
</div>
|
||||
<div class="range-block-counter">
|
||||
<div contenteditable="true" data-for="randomizer_fluctuation" id="randomizer_fluctuation_counter">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
$('#extensions_settings').append(html);
|
||||
$('#ai_response_configuration .range-block-counter').each(addRandomizeButton);
|
||||
$('#randomizer_enabled').on('input', onRandomizerEnabled);
|
||||
$('#randomizer_enabled').prop('checked', extension_settings.randomizer.enabled).trigger('input');
|
||||
$('#randomizer_fluctuation').val(extension_settings.randomizer.fluctuation).trigger('input');
|
||||
$('#randomizer_fluctuation_counter').text(extension_settings.randomizer.fluctuation);
|
||||
$('#randomizer_fluctuation').on('input', function () {
|
||||
const value = parseFloat($(this).val());
|
||||
$('#randomizer_fluctuation_counter').text(value);
|
||||
extension_settings.randomizer.fluctuation = value;
|
||||
console.debug('Randomizer fluctuation:', extension_settings.randomizer.fluctuation);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
});
|
12
public/scripts/extensions/randomize/manifest.json
Normal file
12
public/scripts/extensions/randomize/manifest.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"display_name": "Parameter Randomizer",
|
||||
"loading_order": 15,
|
||||
"requires": [],
|
||||
"optional": [],
|
||||
"js": "index.js",
|
||||
"css": "style.css",
|
||||
"author": "Cohee#1207",
|
||||
"version": "1.0.0",
|
||||
"generate_interceptor": "randomizerInterceptor",
|
||||
"homePage": "https://github.com/SillyTavern/SillyTavern"
|
||||
}
|
0
public/scripts/extensions/randomize/style.css
Normal file
0
public/scripts/extensions/randomize/style.css
Normal file
@@ -56,13 +56,7 @@
|
||||
|
||||
<div class="flex-container">
|
||||
<div class="wi-enter-footer-text flex-container flexFlowColumn flexNoGap alignitemsstart">
|
||||
<small>Placement</small>
|
||||
<div>
|
||||
<label class="checkbox flex-container">
|
||||
<input type="checkbox" name="replace_position" value="0">
|
||||
<span data-i18n="Author's Note">Markdown Display</span>
|
||||
</label>
|
||||
</div>
|
||||
<small>Affects</small>
|
||||
<div>
|
||||
<label class="checkbox flex-container">
|
||||
<input type="checkbox" name="replace_position" value="1">
|
||||
@@ -94,6 +88,10 @@
|
||||
<input type="checkbox" name="disabled" />
|
||||
<span data-i18n="Disabled">Disabled</span>
|
||||
</label>
|
||||
<label class="checkbox flex-container">
|
||||
<input type="checkbox" name="only_format_display" />
|
||||
<span data-i18n="Only Format Display">Only Format Display</span>
|
||||
</label>
|
||||
<label class="checkbox flex-container">
|
||||
<input type="checkbox" name="run_on_edit" />
|
||||
<span data-i18n="Run On Edit">Run On Edit</span>
|
||||
|
@@ -7,6 +7,7 @@ export {
|
||||
}
|
||||
|
||||
const regex_placement = {
|
||||
// MD Display is deprecated. Do not use.
|
||||
MD_DISPLAY: 0,
|
||||
USER_INPUT: 1,
|
||||
AI_OUTPUT: 2,
|
||||
@@ -38,13 +39,17 @@ function regexFromString(input) {
|
||||
}
|
||||
|
||||
// Parent function to fetch a regexed version of a raw string
|
||||
function getRegexedString(rawString, placement, { characterOverride } = {}) {
|
||||
function getRegexedString(rawString, placement, { characterOverride, isMarkdown } = {}) {
|
||||
let finalString = rawString;
|
||||
if (extension_settings.disabledExtensions.includes("regex") || !rawString || placement === undefined) {
|
||||
return finalString;
|
||||
}
|
||||
|
||||
extension_settings.regex.forEach((script) => {
|
||||
if (script.markdownOnly && !isMarkdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (script.placement.includes(placement)) {
|
||||
finalString = runRegexScript(script, finalString, { characterOverride });
|
||||
}
|
||||
|
@@ -48,14 +48,12 @@ async function saveRegexScript(regexScript, existingScriptIndex) {
|
||||
saveSettingsDebounced();
|
||||
await loadRegexScripts();
|
||||
|
||||
// Markdown is global, so reload the chat.
|
||||
if (regexScript.placement.includes(regex_placement.MD_DISPLAY)) {
|
||||
// Reload the current chat to undo previous markdown
|
||||
const currentChatId = getCurrentChatId();
|
||||
if (currentChatId !== undefined && currentChatId !== null) {
|
||||
await reloadCurrentChat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRegexScript({ existingId }) {
|
||||
let scriptName = $(`#${existingId}`).find('.regex_script_name').text();
|
||||
@@ -113,6 +111,9 @@ async function onRegexEditorOpenClick(existingId) {
|
||||
editorHtml
|
||||
.find(`input[name="disabled"]`)
|
||||
.prop("checked", existingScript.disabled ?? false);
|
||||
editorHtml
|
||||
.find(`input[name="only_format_display"]`)
|
||||
.prop("checked", existingScript.markdownOnly ?? false);
|
||||
editorHtml
|
||||
.find(`input[name="run_on_edit"]`)
|
||||
.prop("checked", existingScript.runOnEdit ?? false);
|
||||
@@ -130,6 +131,10 @@ async function onRegexEditorOpenClick(existingId) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
editorHtml
|
||||
.find(`input[name="only_format_display"]`)
|
||||
.prop("checked", true);
|
||||
|
||||
editorHtml
|
||||
.find(`input[name="run_on_edit"]`)
|
||||
.prop("checked", true);
|
||||
@@ -157,6 +162,10 @@ async function onRegexEditorOpenClick(existingId) {
|
||||
editorHtml
|
||||
.find(`input[name="disabled"]`)
|
||||
.prop("checked"),
|
||||
markdownOnly:
|
||||
editorHtml
|
||||
.find(`input[name="only_format_display"]`)
|
||||
.prop("checked"),
|
||||
runOnEdit:
|
||||
editorHtml
|
||||
.find(`input[name="run_on_edit"]`)
|
||||
@@ -176,9 +185,36 @@ async function onRegexEditorOpenClick(existingId) {
|
||||
}
|
||||
}
|
||||
|
||||
// Common settings migration function. Some parts will eventually be removed
|
||||
// TODO: Maybe migrate placement to strings?
|
||||
function migrateSettings() {
|
||||
let performSave = false;
|
||||
|
||||
// Current: If MD Display is present in placement, remove it and add new placements/MD option
|
||||
extension_settings.regex.forEach((script) => {
|
||||
if (script.placement.includes(regex_placement.MD_DISPLAY)) {
|
||||
script.placement = script.placement.length === 1 ?
|
||||
Object.values(regex_placement).filter((e) => e !== regex_placement.MD_DISPLAY) :
|
||||
script.placement = script.placement.filter((e) => e !== regex_placement.MD_DISPLAY);
|
||||
|
||||
script.markdownOnly = true
|
||||
|
||||
performSave = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (performSave) {
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for loading in sequence with other extensions
|
||||
// NOTE: Always puts extension at the top of the list, but this is fine since it's static
|
||||
jQuery(async () => {
|
||||
if (extension_settings.regex) {
|
||||
migrateSettings();
|
||||
}
|
||||
|
||||
// Manually disable the extension since static imports auto-import the JS file
|
||||
if (extension_settings.disabledExtensions.includes("regex")) {
|
||||
return;
|
||||
|
@@ -48,7 +48,7 @@ If you have any objections to these requirements, please mention them specifical
|
||||
If you accept the requirements, please confirm this by replying with "${DEFAULT_JAILBREAK_RESPONSE}", and nothing more. Upon receiving your accurate confirmation message, I will specify the context of the scene and {{char}}'s characteristics, background, and personality in the next message.`;
|
||||
|
||||
const DEFAULT_CHARACTER_NUDGE_MESSAGE = "[Unless otherwise stated by {{user}}, your the next response shall only be written from the point of view of {{char}}. Do not seek approval of your writing style at the end of the response. Never reply with a full stop.]";
|
||||
const DEFAULT_IMPERSONATION_PROMPT = "[Write a reply only from the point of view of {{user}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system.]";
|
||||
const DEFAULT_IMPERSONATION_PROMPT = "[Write a reply only from the point of view of {{user}} {{input}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system.]";
|
||||
|
||||
const poe_settings = {
|
||||
bot: 'a2',
|
||||
|
@@ -1891,7 +1891,7 @@ grammarly-extension {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.menu_button:hover {
|
||||
.menu_button:hover, .menu_button.active {
|
||||
background-color: var(--white30a);
|
||||
}
|
||||
|
||||
@@ -1899,10 +1899,6 @@ grammarly-extension {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#dialogue_del_mes .menu_button {
|
||||
|
||||
margin-left: 25px;
|
||||
@@ -2340,6 +2336,7 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin):not(#lm_button
|
||||
font-size: calc(var(--mainFontSize) * 0.95);
|
||||
color: var(--SmartThemeBodyColor);
|
||||
flex: 1;
|
||||
gap: 5px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user