mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge pull request #1680 from valadaptive/macro-separation
Pass macro variables into evaluateMacros
This commit is contained in:
@@ -2140,10 +2140,42 @@ function scrollChatToBottom() {
|
|||||||
* @param {*} _name2 - The name of the character. Uses global name2 if not provided.
|
* @param {*} _name2 - The name of the character. Uses global name2 if not provided.
|
||||||
* @param {*} _original - The original message for {{original}} substitution.
|
* @param {*} _original - The original message for {{original}} substitution.
|
||||||
* @param {*} _group - The group members list for {{group}} substitution.
|
* @param {*} _group - The group members list for {{group}} substitution.
|
||||||
|
* @param {boolean} _replaceCharacterCard - Whether to replace character card macros.
|
||||||
* @returns {string} The string with substituted parameters.
|
* @returns {string} The string with substituted parameters.
|
||||||
*/
|
*/
|
||||||
function substituteParams(content, _name1, _name2, _original, _group, _replaceCharacterCard = true) {
|
function substituteParams(content, _name1, _name2, _original, _group, _replaceCharacterCard = true) {
|
||||||
return evaluateMacros(content, _name1 ?? name1, _name2 ?? name2, _original, _group ?? name2, _replaceCharacterCard);
|
const environment = {};
|
||||||
|
|
||||||
|
if (typeof _original === 'string') {
|
||||||
|
let originalSubstituted = false;
|
||||||
|
environment.original = () => {
|
||||||
|
if (originalSubstituted) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
originalSubstituted = true;
|
||||||
|
return _original;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_replaceCharacterCard) {
|
||||||
|
const fields = getCharacterCardFields();
|
||||||
|
environment.charPrompt = fields.system || '';
|
||||||
|
environment.charJailbreak = fields.jailbreak || '';
|
||||||
|
environment.description = fields.description || '';
|
||||||
|
environment.personality = fields.personality || '';
|
||||||
|
environment.scenario = fields.scenario || '';
|
||||||
|
environment.persona = fields.persona || '';
|
||||||
|
environment.mesExamples = fields.mesExamples || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be substituted last so that they're replaced inside {{description}}
|
||||||
|
// TODO: evaluate macros recursively so we don't need to rely on substitution order
|
||||||
|
environment.user = _name1 ?? name1;
|
||||||
|
environment.char = _name2 ?? name2;
|
||||||
|
environment.group = environment.charIfNotGroup = _group ?? name2;
|
||||||
|
|
||||||
|
return evaluateMacros(content, environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2443,7 +2475,7 @@ function showStopButton() {
|
|||||||
|
|
||||||
function hideStopButton() {
|
function hideStopButton() {
|
||||||
// prevent NOOP, because hideStopButton() gets called multiple times
|
// prevent NOOP, because hideStopButton() gets called multiple times
|
||||||
if($('#mes_stop').css('display') !== 'none') {
|
if ($('#mes_stop').css('display') !== 'none') {
|
||||||
$('#mes_stop').css({ 'display': 'none' });
|
$('#mes_stop').css({ 'display': 'none' });
|
||||||
eventSource.emit(event_types.GENERATION_ENDED, chat.length);
|
eventSource.emit(event_types.GENERATION_ENDED, chat.length);
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { chat, main_api, getMaxContextSize, getCharacterCardFields } from '../script.js';
|
import { chat, main_api, getMaxContextSize } from '../script.js';
|
||||||
import { timestampToMoment, isDigitsOnly } from './utils.js';
|
import { timestampToMoment, isDigitsOnly } from './utils.js';
|
||||||
import { textgenerationwebui_banned_in_macros } from './textgen-settings.js';
|
import { textgenerationwebui_banned_in_macros } from './textgen-settings.js';
|
||||||
import { replaceInstructMacros } from './instruct-mode.js';
|
import { replaceInstructMacros } from './instruct-mode.js';
|
||||||
@@ -201,56 +201,41 @@ function diceRollReplace(input, invalidRollPlaceholder = '') {
|
|||||||
/**
|
/**
|
||||||
* Substitutes {{macro}} parameters in a string.
|
* Substitutes {{macro}} parameters in a string.
|
||||||
* @param {string} content - The string to substitute parameters in.
|
* @param {string} content - The string to substitute parameters in.
|
||||||
* @param {*} _name1 - The name of the user.
|
* @param {Object<string, *>} env - Map of macro names to the values they'll be substituted with. If the param
|
||||||
* @param {*} _name2 - The name of the character.
|
* values are functions, those functions will be called and their return values are used.
|
||||||
* @param {*} _original - The original message for {{original}} substitution.
|
|
||||||
* @param {*} _group - The group members list for {{group}} substitution.
|
|
||||||
* @param {boolean} _replaceCharacterCard - Whether to replace character card macros.
|
|
||||||
* @returns {string} The string with substituted parameters.
|
* @returns {string} The string with substituted parameters.
|
||||||
*/
|
*/
|
||||||
export function evaluateMacros(content, _name1, _name2, _original, _group, _replaceCharacterCard = true) {
|
export function evaluateMacros(content, env) {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace {{original}} with the original message
|
|
||||||
// Note: only replace the first instance of {{original}}
|
|
||||||
// This will hopefully prevent the abuse
|
|
||||||
if (typeof _original === 'string') {
|
|
||||||
content = content.replace(/{{original}}/i, _original);
|
|
||||||
}
|
|
||||||
content = diceRollReplace(content);
|
content = diceRollReplace(content);
|
||||||
content = replaceInstructMacros(content);
|
content = replaceInstructMacros(content);
|
||||||
content = replaceVariableMacros(content);
|
content = replaceVariableMacros(content);
|
||||||
content = content.replace(/{{newline}}/gi, '\n');
|
content = content.replace(/{{newline}}/gi, '\n');
|
||||||
content = content.replace(/{{input}}/gi, String($('#send_textarea').val()));
|
content = content.replace(/{{input}}/gi, String($('#send_textarea').val()));
|
||||||
|
|
||||||
if (_replaceCharacterCard) {
|
// Substitute passed-in variables
|
||||||
const fields = getCharacterCardFields();
|
for (const varName in env) {
|
||||||
content = content.replace(/{{charPrompt}}/gi, fields.system || '');
|
if (!Object.hasOwn(env, varName)) continue;
|
||||||
content = content.replace(/{{charJailbreak}}/gi, fields.jailbreak || '');
|
|
||||||
content = content.replace(/{{description}}/gi, fields.description || '');
|
const param = env[varName];
|
||||||
content = content.replace(/{{personality}}/gi, fields.personality || '');
|
content = content.replace(new RegExp(`{{${varName}}}`, 'gi'), param);
|
||||||
content = content.replace(/{{scenario}}/gi, fields.scenario || '');
|
|
||||||
content = content.replace(/{{persona}}/gi, fields.persona || '');
|
|
||||||
content = content.replace(/{{mesExamples}}/gi, fields.mesExamples || '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
|
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
|
||||||
content = content.replace(/{{user}}/gi, _name1);
|
|
||||||
content = content.replace(/{{char}}/gi, _name2);
|
|
||||||
content = content.replace(/{{charIfNotGroup}}/gi, _group);
|
|
||||||
content = content.replace(/{{group}}/gi, _group);
|
|
||||||
content = content.replace(/{{lastMessage}}/gi, getLastMessage());
|
content = content.replace(/{{lastMessage}}/gi, getLastMessage());
|
||||||
content = content.replace(/{{lastMessageId}}/gi, getLastMessageId());
|
content = content.replace(/{{lastMessageId}}/gi, getLastMessageId());
|
||||||
content = content.replace(/{{firstIncludedMessageId}}/gi, getFirstIncludedMessageId());
|
content = content.replace(/{{firstIncludedMessageId}}/gi, getFirstIncludedMessageId());
|
||||||
content = content.replace(/{{lastSwipeId}}/gi, getLastSwipeId());
|
content = content.replace(/{{lastSwipeId}}/gi, getLastSwipeId());
|
||||||
content = content.replace(/{{currentSwipeId}}/gi, getCurrentSwipeId());
|
content = content.replace(/{{currentSwipeId}}/gi, getCurrentSwipeId());
|
||||||
|
|
||||||
content = content.replace(/<USER>/gi, _name1);
|
// Legacy non-macro substitutions
|
||||||
content = content.replace(/<BOT>/gi, _name2);
|
content = content.replace(/<USER>/gi, typeof env.user === 'function' ? env.user() : env.user);
|
||||||
content = content.replace(/<CHARIFNOTGROUP>/gi, _group);
|
content = content.replace(/<BOT>/gi, typeof env.char === 'function' ? env.char() : env.char);
|
||||||
content = content.replace(/<GROUP>/gi, _group);
|
content = content.replace(/<CHARIFNOTGROUP>/gi, typeof env.group === 'function' ? env.group() : env.group);
|
||||||
|
content = content.replace(/<GROUP>/gi, typeof env.group === 'function' ? env.group() : env.group);
|
||||||
|
|
||||||
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');
|
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user