mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-01-20 13:38:49 +01:00
/inject command to add prompt injections
This commit is contained in:
parent
4f9f89c682
commit
b0d21659eb
@ -151,7 +151,7 @@ import {
|
||||
} from "./scripts/utils.js";
|
||||
|
||||
import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, loadExtensionSettings, processExtensionHelpers, registerExtensionHelper, renderExtensionTemplate, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
|
||||
import { COMMENT_NAME_DEFAULT, executeSlashCommands, getSlashCommandsHelp, registerSlashCommand } from "./scripts/slash-commands.js";
|
||||
import { COMMENT_NAME_DEFAULT, executeSlashCommands, getSlashCommandsHelp, processChatSlashCommands, registerSlashCommand } from "./scripts/slash-commands.js";
|
||||
import {
|
||||
tag_map,
|
||||
tags,
|
||||
@ -188,7 +188,7 @@ import {
|
||||
formatInstructModeSystemPrompt,
|
||||
replaceInstructMacros,
|
||||
} from "./scripts/instruct-mode.js";
|
||||
import { applyLocale } from "./scripts/i18n.js";
|
||||
import { applyLocale, initLocales } from "./scripts/i18n.js";
|
||||
import { getFriendlyTokenizerName, getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from "./scripts/tokenizers.js";
|
||||
import { createPersona, initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
|
||||
import { getBackgrounds, initBackgrounds } from "./scripts/backgrounds.js";
|
||||
@ -324,6 +324,7 @@ export const eventSource = new EventEmitter();
|
||||
|
||||
eventSource.on(event_types.MESSAGE_RECEIVED, processExtensionHelpers);
|
||||
eventSource.on(event_types.MESSAGE_SENT, processExtensionHelpers);
|
||||
eventSource.on(event_types.CHAT_CHANGED, processChatSlashCommands);
|
||||
|
||||
const characterGroupOverlay = new BulkEditOverlay();
|
||||
const characterContextMenu = new CharacterContextMenu(characterGroupOverlay);
|
||||
@ -731,6 +732,7 @@ async function firstLoadInit() {
|
||||
|
||||
getSystemMessages();
|
||||
sendSystemMessage(system_message_types.WELCOME);
|
||||
initLocales();
|
||||
await readSecretState();
|
||||
await getClientVersion();
|
||||
await getSettings();
|
||||
|
@ -105,7 +105,7 @@ function addLanguagesToDropdown() {
|
||||
}
|
||||
}
|
||||
|
||||
jQuery(async () => {
|
||||
export function initLocales() {
|
||||
waitUntilCondition(() => !!localeData);
|
||||
applyLocale();
|
||||
addLanguagesToDropdown();
|
||||
@ -124,4 +124,4 @@ jQuery(async () => {
|
||||
|
||||
registerDebugFunction('getMissingTranslations', 'Get missing translations', 'Detects missing localization data and dumps the data into the browser console.', getMissingTranslations);
|
||||
registerDebugFunction('applyLocale', 'Apply locale', 'Reapplies the currently selected locale to the page.', applyLocale);
|
||||
});
|
||||
};
|
||||
|
@ -30,13 +30,15 @@ import {
|
||||
activateSendButtons,
|
||||
main_api,
|
||||
is_send_press,
|
||||
extension_prompt_types,
|
||||
setExtensionPrompt,
|
||||
} from "../script.js";
|
||||
import { getMessageTimeStamp } from "./RossAscends-mods.js";
|
||||
import { findGroupMemberId, groups, is_group_generating, resetSelectedGroup, saveGroupChat, selected_group } from "./group-chats.js";
|
||||
import { getRegexedString, regex_placement } from "./extensions/regex/engine.js";
|
||||
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from "./power-user.js";
|
||||
import { autoSelectPersona } from "./personas.js";
|
||||
import { getContext } from "./extensions.js";
|
||||
import { getContext, saveMetadataDebounced } from "./extensions.js";
|
||||
import { hideChatMessage, unhideChatMessage } from "./chats.js";
|
||||
import { delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence } from "./utils.js";
|
||||
import { registerVariableCommands, resolveVariable } from "./variables.js";
|
||||
@ -153,7 +155,7 @@ parser.addCommand('go', goToCharacterCallback, ['char'], '<span class="monospace
|
||||
parser.addCommand('sysgen', generateSystemMessage, [], '<span class="monospace">(prompt)</span> – generates a system message using a specified prompt', true, true);
|
||||
parser.addCommand('ask', askCharacter, [], '<span class="monospace">(prompt)</span> – asks a specified character card a prompt', true, true);
|
||||
parser.addCommand('delname', deleteMessagesByNameCallback, ['cancel'], '<span class="monospace">(name)</span> – deletes all messages attributed to a specified name', true, true);
|
||||
parser.addCommand('send', sendUserMessageCallback, ['add'], '<span class="monospace">(text)</span> – adds a user message to the chat log without triggering a generation', true, true);
|
||||
parser.addCommand('send', sendUserMessageCallback, [], '<span class="monospace">(text)</span> – adds a user message to the chat log without triggering a generation', true, true);
|
||||
parser.addCommand('trigger', triggerGenerationCallback, [], ' – triggers a message generation. If in group, can trigger a message for the specified group member index or name.', true, true);
|
||||
parser.addCommand('hide', hideMessageCallback, [], '<span class="monospace">(message index or range)</span> – hides a chat message from the prompt', true, true);
|
||||
parser.addCommand('unhide', unhideMessageCallback, [], '<span class="monospace">(message index or range)</span> – unhides a message from the prompt', true, true);
|
||||
@ -182,11 +184,114 @@ parser.addCommand('buttons', buttonsCallback, [], '<span class="monospace">label
|
||||
parser.addCommand('trimtokens', trimTokensCallback, [], '<span class="monospace">limit=number (direction=start/end [text])</span> – trims the start or end of text to the specified number of tokens.', true, true);
|
||||
parser.addCommand('trimstart', trimStartCallback, [], '<span class="monospace">(text)</span> – trims the text to the start of the first full sentence.', true, true);
|
||||
parser.addCommand('trimend', trimEndCallback, [], '<span class="monospace">(text)</span> – trims the text to the end of the last full sentence.', true, true);
|
||||
parser.addCommand('inject', injectCallback, [], '<span class="monospace">id=injectId (position=before/after/chat depth=number [text])</span> – injects a text into the LLM prompt for the current chat. Requires a unique injection ID. Positions: "before" main prompt, "after" main prompt, in-"chat" (default: after). Depth: injection depth for the prompt (default: 4).', true, true);
|
||||
parser.addCommand('listinjects', listInjectsCallback, [], ' – lists all script injections for the current chat.', true, true);
|
||||
parser.addCommand('flushinjects', flushInjectsCallback, [], ' – removes all script injections for the current chat.', true, true);
|
||||
registerVariableCommands();
|
||||
|
||||
const NARRATOR_NAME_KEY = 'narrator_name';
|
||||
const NARRATOR_NAME_DEFAULT = 'System';
|
||||
export const COMMENT_NAME_DEFAULT = 'Note';
|
||||
const SCRIPT_PROMPT_KEY = 'script_inject_';
|
||||
|
||||
function injectCallback(args, value) {
|
||||
const positions = {
|
||||
'before': extension_prompt_types.BEFORE_PROMPT,
|
||||
'after': extension_prompt_types.IN_PROMPT,
|
||||
'chat': extension_prompt_types.IN_CHAT,
|
||||
};
|
||||
|
||||
const id = resolveVariable(args?.id);
|
||||
|
||||
if (!id) {
|
||||
console.warn('WARN: No ID provided for /inject command');
|
||||
toastr.warning('No ID provided for /inject command');
|
||||
return '';
|
||||
}
|
||||
|
||||
const defaultPosition = 'after';
|
||||
const defaultDepth = 4;
|
||||
const positionValue = args?.position ?? defaultPosition;
|
||||
const position = positions[positionValue] ?? positions[defaultPosition];
|
||||
const depthValue = Number(args?.depth) ?? defaultDepth;
|
||||
const depth = isNaN(depthValue) ? defaultDepth : depthValue;
|
||||
value = value || '';
|
||||
|
||||
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
||||
|
||||
if (!chat_metadata.script_injects) {
|
||||
chat_metadata.script_injects = {};
|
||||
}
|
||||
|
||||
chat_metadata.script_injects[id] = {
|
||||
value,
|
||||
position,
|
||||
depth,
|
||||
};
|
||||
|
||||
setExtensionPrompt(prefixedId, value, position, depth);
|
||||
saveMetadataDebounced();
|
||||
return '';
|
||||
}
|
||||
|
||||
function listInjectsCallback() {
|
||||
if (!chat_metadata.script_injects) {
|
||||
toastr.info('No script injections for the current chat');
|
||||
return '';
|
||||
}
|
||||
|
||||
const injects = Object.entries(chat_metadata.script_injects)
|
||||
.map(([id, inject]) => {
|
||||
const position = Object.entries(extension_prompt_types);
|
||||
const positionName = position.find(([_, value]) => value === inject.position)?.[0] ?? 'unknown';
|
||||
return `* **${id}**: <code>${inject.value}</code> (${positionName}, depth: ${inject.depth})`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
const messageText = `### Script injections:\n${injects}`;
|
||||
const htmlMessage = DOMPurify.sanitize(converter.makeHtml(messageText));
|
||||
|
||||
sendSystemMessage(system_message_types.GENERIC, htmlMessage);
|
||||
}
|
||||
|
||||
function flushInjectsCallback() {
|
||||
if (!chat_metadata.script_injects) {
|
||||
return '';
|
||||
}
|
||||
|
||||
for (const [id, inject] of Object.entries(chat_metadata.script_injects)) {
|
||||
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
||||
setExtensionPrompt(prefixedId, '', inject.position, inject.depth);
|
||||
}
|
||||
|
||||
chat_metadata.script_injects = {};
|
||||
saveMetadataDebounced();
|
||||
return '';
|
||||
}
|
||||
|
||||
export function processChatSlashCommands() {
|
||||
const context = getContext();
|
||||
|
||||
if (!(context.chatMetadata.script_injects)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const id of Object.keys(context.extensionPrompts)) {
|
||||
if (!id.startsWith(SCRIPT_PROMPT_KEY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log('Removing script injection', id);
|
||||
delete context.extensionPrompts[id];
|
||||
}
|
||||
|
||||
for (const [id, inject] of Object.entries(context.chatMetadata.script_injects)) {
|
||||
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
||||
console.log('Adding script injection', id);
|
||||
setExtensionPrompt(prefixedId, inject.value, inject.position, inject.depth);
|
||||
}
|
||||
}
|
||||
|
||||
function setInputCallback(_, value) {
|
||||
$('#send_textarea').val(value || '').trigger('input');
|
||||
|
Loading…
Reference in New Issue
Block a user