Refactor /listinjects, deprecate its "format" arg

62fd450c592653fd256eaf631372cd05c72745ae

Wolfsblvt <wolfsblvt@gmail.com>

2 files changed, +45 -25Showing whitespace changes
public/scripts/slash-commands.js+35 -19
@@ -1525,11 +1525,20 @@ export function initDefaultSlashCommands() {
1525 name: 'listinjects',1525 name: 'listinjects',
1526 callback: listInjectsCallback,1526 callback: listInjectsCallback,
1527 helpString: 'Lists all script injections for the current chat. Displays injects in a popup by default. Use the <code>format</code> argument to change the output format.',1527 helpString: 'Lists all script injections for the current chat. Displays injects in a popup by default. Use the <code>format</code> argument to change the output format.',
1528 returns: 'JSON object of script injections',1528 returns: 'Optionalls the JSON object of script injections',
1529 namedArgumentList: [1529 namedArgumentList: [
1530 SlashCommandNamedArgument.fromProps({1530 SlashCommandNamedArgument.fromProps({
1531 name: 'return',
1532 description: 'The way how you want the return value to be provided',
1533 typeList: [ARGUMENT_TYPE.STRING],
1534 defaultValue: 'object',
1535 enumList: slashCommandReturnHelper.enumList({ allowPipe: false, allowObject: true, allowChat: true, allowPopup: true, allowTextVersion: false }),
1536 forceEnum: true,
1537 }),
1538 // TODO remove some day
1539 SlashCommandNamedArgument.fromProps({
1531 name: 'format',1540 name: 'format',
1532 description: 'output format',1541 description: 'DEPRECATED - use "return" instead - output format',
1533 typeList: [ARGUMENT_TYPE.STRING],1542 typeList: [ARGUMENT_TYPE.STRING],
1534 isRequired: true,1543 isRequired: true,
1535 forceEnum: true,1544 forceEnum: true,
@@ -1798,37 +1807,44 @@ function injectCallback(args, value) {
1798}1807}
17991808
1800async function listInjectsCallback(args) {1809async function listInjectsCallback(args) {
1810 /** @type {import('./slash-commands/SlashCommandReturnHelper.js').SlashCommandReturnType} */
1811 let returnType = args.return;
1812
1813 // Old legacy return type handling
1814 if (args.format) {
1815 toastr.warning(`Legacy argument 'format' with value '${args.format}' is deprecated. Please use 'return' instead. Routing to the correct return type...`, 'Deprecation warning');
1801 const type = String(args?.format).toLowerCase().trim();1816 const type = String(args?.format).toLowerCase().trim();
1802 if (!chat_metadata.script_injects || !Object.keys(chat_metadata.script_injects).length) {1817 if (!chat_metadata.script_injects || !Object.keys(chat_metadata.script_injects).length) {
1803 type !== 'none' && toastr.info('No script injections for the current chat');1818 type !== 'none' && toastr.info('No script injections for the current chat');
1804 return JSON.stringify({});
1805 }1819 }
1806
1807 const injects = Object.entries(chat_metadata.script_injects)
1808 .map(([id, inject]) => {
1809 const position = Object.entries(extension_prompt_types);
1810 const positionName = position.find(([_, value]) => value === inject.position)?.[0] ?? 'unknown';
1811 return `* **${id}**: <code>${inject.value}</code> (${positionName}, depth: ${inject.depth}, scan: ${inject.scan ?? false}, role: ${inject.role ?? extension_prompt_roles.SYSTEM})`;
1812 })
1813 .join('\n');
1814
1815 const converter = new showdown.Converter();
1816 const messageText = `### Script injections:\n${injects}`;
1817 const htmlMessage = DOMPurify.sanitize(converter.makeHtml(messageText));
1818
1819 switch (type) {1820 switch (type) {
1820 case 'none':1821 case 'none':
1822 returnType = 'none';
1821 break;1823 break;
1822 case 'chat':1824 case 'chat':
1823 sendSystemMessage(system_message_types.GENERIC, htmlMessage);1825 returnType = 'chat-html';
1824 break;1826 break;
1825 case 'popup':1827 case 'popup':
1826 default:1828 default:
1827 await callGenericPopup(htmlMessage, POPUP_TYPE.TEXT);1829 returnType = 'popup-html';
1828 break;1830 break;
1829 }1831 }
1832 }
1833
1834 // Now the actual new return type handling
1835
1836 const buildTextValue = (injects) => {
1837 const injectsStr = Object.entries(injects)
1838 .map(([id, inject]) => {
1839 const position = Object.entries(extension_prompt_types);
1840 const positionName = position.find(([_, value]) => value === inject.position)?.[0] ?? 'unknown';
1841 return `* **${id}**: <code>${inject.value}</code> (${positionName}, depth: ${inject.depth}, scan: ${inject.scan ?? false}, role: ${inject.role ?? extension_prompt_roles.SYSTEM})`;
1842 })
1843 .join('\n');
1844 return `### Script injections:\n${injectsStr}`;
1845 };
18301846
1831 return JSON.stringify(chat_metadata.script_injects);1847 return await slashCommandReturnHelper.doReturn(returnType ?? 'object', chat_metadata.script_injects, { objectToStringFunc: buildTextValue });
1832}1848}
18331849
1834/**1850/**
public/scripts/slash-commands/SlashCommandReturnHelper.js+10 -6
@@ -7,6 +7,9 @@ import { enumTypes, SlashCommandEnumValue } from './SlashCommandEnumValue.js';
7/** @typedef {'pipe'|'object'|'chat-html'|'chat-text'|'popup-html'|'popup-text'|'toast-html'|'toast-text'|'console'|'none'} SlashCommandReturnType */7/** @typedef {'pipe'|'object'|'chat-html'|'chat-text'|'popup-html'|'popup-text'|'toast-html'|'toast-text'|'console'|'none'} SlashCommandReturnType */
88
9export const slashCommandReturnHelper = {9export const slashCommandReturnHelper = {
10 // Without this, VSCode formatter fucks up JS docs. Don't ask me why.
11 _: false,
12
10 /**13 /**
11 * Gets/creates the enum list of types of return relevant for a slash command14 * Gets/creates the enum list of types of return relevant for a slash command
12 *15 *
@@ -15,18 +18,19 @@ export const slashCommandReturnHelper = {
15 * @param {boolean} [options.allowObject=false] Allow option to return the value as an object18 * @param {boolean} [options.allowObject=false] Allow option to return the value as an object
16 * @param {boolean} [options.allowChat=false] Allow option to return the value as a chat message19 * @param {boolean} [options.allowChat=false] Allow option to return the value as a chat message
17 * @param {boolean} [options.allowPopup=false] Allow option to return the value as a popup20 * @param {boolean} [options.allowPopup=false] Allow option to return the value as a popup
21 * @param {boolean}[options.allowTextVersion=true] Used in combination with chat/popup/toast, some of them do not make sense for text versions, e.g.if you are building a HTML string anyway
18 * @returns {SlashCommandEnumValue[]} The enum list22 * @returns {SlashCommandEnumValue[]} The enum list
19 */23 */
20 enumList: ({ allowPipe = true, allowObject = false, allowChat = false, allowPopup = false } = {}) => [24 enumList: ({ allowPipe = true, allowObject = false, allowChat = false, allowPopup = false, allowTextVersion = true } = {}) => [
21 allowPipe && new SlashCommandEnumValue('pipe', 'Return to the pipe for the next command', enumTypes.name, '|'),25 allowPipe && new SlashCommandEnumValue('pipe', 'Return to the pipe for the next command', enumTypes.name, '|'),
22 allowObject && new SlashCommandEnumValue('object', 'Return as an object to the pipe for the next command', enumTypes.variable, enumIcons.dictionary),26 allowObject && new SlashCommandEnumValue('object', 'Return as an object to the pipe for the next command', enumTypes.variable, enumIcons.dictionary),
23 allowChat && new SlashCommandEnumValue('chat-html', 'Sending a chat message with the return value - Can display HTML', enumTypes.command, enumIcons.message),27 allowChat && new SlashCommandEnumValue('chat-html', 'Sending a chat message with the return value - Can display HTML', enumTypes.command, enumIcons.message),
24 allowChat && new SlashCommandEnumValue('chat-text', 'Sending a chat message with the return value - Will only display as text', enumTypes.qr, enumIcons.message),28 allowChat && allowTextVersion && new SlashCommandEnumValue('chat-text', 'Sending a chat message with the return value - Will only display as text', enumTypes.qr, enumIcons.message),
25 new SlashCommandEnumValue('popup-html', 'Showing as a popup with the return value - Can display HTML', enumTypes.command, enumIcons.popup),29 allowPopup && new SlashCommandEnumValue('popup-html', 'Showing as a popup with the return value - Can display HTML', enumTypes.command, enumIcons.popup),
26 new SlashCommandEnumValue('popup-text', 'Showing as a popup with the return value - Will only display as text', enumTypes.qr, enumIcons.popup),30 allowPopup && allowTextVersion && new SlashCommandEnumValue('popup-text', 'Showing as a popup with the return value - Will only display as text', enumTypes.qr, enumIcons.popup),
27 new SlashCommandEnumValue('toast-html', 'Show the return value as a toast notification - Can display HTML', enumTypes.command, 'ℹ️'),31 new SlashCommandEnumValue('toast-html', 'Show the return value as a toast notification - Can display HTML', enumTypes.command, 'ℹ️'),
28 new SlashCommandEnumValue('toast-text', 'Show the return value as a toast notification - Will only display as text', enumTypes.qr, 'ℹ️'),32 allowTextVersion && new SlashCommandEnumValue('toast-text', 'Show the return value as a toast notification - Will only display as text', enumTypes.qr, 'ℹ️'),
29 new SlashCommandEnumValue('console', 'Log the return value to the console', enumTypes.enum, '>'),33 new SlashCommandEnumValue('console', 'Log the return value (object, if it can be one) to the console', enumTypes.enum, '>'),
30 new SlashCommandEnumValue('none', 'No return value'),34 new SlashCommandEnumValue('none', 'No return value'),
31 ].filter(x => !!x),35 ].filter(x => !!x),
3236