mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-23 15:37:50 +01:00
Add filter arg for inject command
This commit is contained in:
parent
47dea8159e
commit
205f1d7adb
@ -84,6 +84,20 @@ export const parser = new SlashCommandParser();
|
|||||||
const registerSlashCommand = SlashCommandParser.addCommand.bind(SlashCommandParser);
|
const registerSlashCommand = SlashCommandParser.addCommand.bind(SlashCommandParser);
|
||||||
const getSlashCommandsHelp = parser.getHelpString.bind(parser);
|
const getSlashCommandsHelp = parser.getHelpString.bind(parser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a SlashCommandClosure to a filter function that returns a boolean.
|
||||||
|
* @param {SlashCommandClosure} closure
|
||||||
|
* @returns {() => Promise<boolean>}
|
||||||
|
*/
|
||||||
|
function closureToFilter(closure) {
|
||||||
|
return async () => {
|
||||||
|
const localClosure = closure.getCopy();
|
||||||
|
localClosure.onProgress = () => { };
|
||||||
|
const result = await localClosure.execute();
|
||||||
|
return isTrueBoolean(result.pipe);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function initDefaultSlashCommands() {
|
export function initDefaultSlashCommands() {
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: '?',
|
name: '?',
|
||||||
@ -1611,6 +1625,13 @@ export function initDefaultSlashCommands() {
|
|||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'ephemeral', 'remove injection after generation', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
'ephemeral', 'remove injection after generation', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
||||||
),
|
),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'filter',
|
||||||
|
description: 'if a filter is defined, an injection will only be performed if the closure returns true',
|
||||||
|
typeList: [ARGUMENT_TYPE.CLOSURE],
|
||||||
|
isRequired: false,
|
||||||
|
acceptsMultiple: false,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
new SlashCommandArgument(
|
||||||
@ -1901,6 +1922,11 @@ const NARRATOR_NAME_DEFAULT = 'System';
|
|||||||
export const COMMENT_NAME_DEFAULT = 'Note';
|
export const COMMENT_NAME_DEFAULT = 'Note';
|
||||||
const SCRIPT_PROMPT_KEY = 'script_inject_';
|
const SCRIPT_PROMPT_KEY = 'script_inject_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new script injection to the chat.
|
||||||
|
* @param {import('./slash-commands/SlashCommand.js').NamedArguments} args Named arguments
|
||||||
|
* @param {import('./slash-commands/SlashCommand.js').UnnamedArguments} value Unnamed argument
|
||||||
|
*/
|
||||||
function injectCallback(args, value) {
|
function injectCallback(args, value) {
|
||||||
const positions = {
|
const positions = {
|
||||||
'before': extension_prompt_types.BEFORE_PROMPT,
|
'before': extension_prompt_types.BEFORE_PROMPT,
|
||||||
@ -1914,8 +1940,8 @@ function injectCallback(args, value) {
|
|||||||
'assistant': extension_prompt_roles.ASSISTANT,
|
'assistant': extension_prompt_roles.ASSISTANT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const id = args?.id;
|
const id = String(args?.id);
|
||||||
const ephemeral = isTrueBoolean(args?.ephemeral);
|
const ephemeral = isTrueBoolean(String(args?.ephemeral));
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
console.warn('WARN: No ID provided for /inject command');
|
console.warn('WARN: No ID provided for /inject command');
|
||||||
@ -1931,7 +1957,9 @@ function injectCallback(args, value) {
|
|||||||
const depth = isNaN(depthValue) ? defaultDepth : depthValue;
|
const depth = isNaN(depthValue) ? defaultDepth : depthValue;
|
||||||
const roleValue = typeof args?.role === 'string' ? args.role.toLowerCase().trim() : Number(args?.role ?? extension_prompt_roles.SYSTEM);
|
const roleValue = typeof args?.role === 'string' ? args.role.toLowerCase().trim() : Number(args?.role ?? extension_prompt_roles.SYSTEM);
|
||||||
const role = roles[roleValue] ?? roles[extension_prompt_roles.SYSTEM];
|
const role = roles[roleValue] ?? roles[extension_prompt_roles.SYSTEM];
|
||||||
const scan = isTrueBoolean(args?.scan);
|
const scan = isTrueBoolean(String(args?.scan));
|
||||||
|
const filter = args?.filter instanceof SlashCommandClosure ? args.filter.rawText : null;
|
||||||
|
const filterFunction = args?.filter instanceof SlashCommandClosure ? closureToFilter(args.filter) : null;
|
||||||
value = value || '';
|
value = value || '';
|
||||||
|
|
||||||
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
||||||
@ -1941,13 +1969,13 @@ function injectCallback(args, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
const inject = { value, position, depth, scan, role };
|
const inject = { value, position, depth, scan, role, filter };
|
||||||
chat_metadata.script_injects[id] = inject;
|
chat_metadata.script_injects[id] = inject;
|
||||||
} else {
|
} else {
|
||||||
delete chat_metadata.script_injects[id];
|
delete chat_metadata.script_injects[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
setExtensionPrompt(prefixedId, value, position, depth, scan, role);
|
setExtensionPrompt(prefixedId, String(value), position, depth, scan, role, filterFunction);
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
|
|
||||||
if (ephemeral) {
|
if (ephemeral) {
|
||||||
@ -1958,7 +1986,7 @@ function injectCallback(args, value) {
|
|||||||
}
|
}
|
||||||
console.log('Removing ephemeral script injection', id);
|
console.log('Removing ephemeral script injection', id);
|
||||||
delete chat_metadata.script_injects[id];
|
delete chat_metadata.script_injects[id];
|
||||||
setExtensionPrompt(prefixedId, '', position, depth, scan, role);
|
setExtensionPrompt(prefixedId, '', position, depth, scan, role, filterFunction);
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
deleted = true;
|
deleted = true;
|
||||||
};
|
};
|
||||||
@ -2053,9 +2081,28 @@ export function processChatSlashCommands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const [id, inject] of Object.entries(context.chatMetadata.script_injects)) {
|
for (const [id, inject] of Object.entries(context.chatMetadata.script_injects)) {
|
||||||
|
/**
|
||||||
|
* Rehydrates a filter closure from a string.
|
||||||
|
* @returns {SlashCommandClosure | null}
|
||||||
|
*/
|
||||||
|
function reviveFilterClosure() {
|
||||||
|
if (!inject.filter) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new SlashCommandParser().parse(inject.filter, true);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Failed to revive filter closure for script injection', id, error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
const prefixedId = `${SCRIPT_PROMPT_KEY}${id}`;
|
||||||
|
const filterClosure = reviveFilterClosure();
|
||||||
|
const filter = filterClosure ? closureToFilter(filterClosure) : null;
|
||||||
console.log('Adding script injection', id);
|
console.log('Adding script injection', id);
|
||||||
setExtensionPrompt(prefixedId, inject.value, inject.position, inject.depth, inject.scan, inject.role);
|
setExtensionPrompt(prefixedId, inject.value, inject.position, inject.depth, inject.scan, inject.role, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user