From db6f782e0f59ad665c7f50837610860743727cd8 Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 16:48:24 +0000 Subject: [PATCH 1/8] add index to /setvar and /setglobalvar --- public/scripts/variables.js | 54 ++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/public/scripts/variables.js b/public/scripts/variables.js index 99175d9c4..39038684a 100644 --- a/public/scripts/variables.js +++ b/public/scripts/variables.js @@ -28,12 +28,33 @@ function getLocalVariable(name, args = {}) { return (localVariable === '' || isNaN(Number(localVariable))) ? (localVariable || '') : Number(localVariable); } -function setLocalVariable(name, value) { +function setLocalVariable(name, value, args = {}) { if (!chat_metadata.variables) { chat_metadata.variables = {}; } - chat_metadata.variables[name] = value; + if (args.index !== undefined) { + try { + let localVariable = JSON.parse(chat_metadata.variables[name] ?? 'null'); + const numIndex = Number(args.index); + if (Number.isNaN(numIndex)) { + if (localVariable === null) { + localVariable = {}; + } + localVariable[args.index] = value; + } else { + if (localVariable === null) { + localVariable = []; + } + localVariable[numIndex] = value; + } + chat_metadata.variables[name] = JSON.stringify(localVariable); + } catch { + // that didn't work + } + } else { + chat_metadata.variables[name] = value; + } saveMetadataDebounced(); return value; } @@ -60,8 +81,29 @@ function getGlobalVariable(name, args = {}) { return (globalVariable === '' || isNaN(Number(globalVariable))) ? (globalVariable || '') : Number(globalVariable); } -function setGlobalVariable(name, value) { - extension_settings.variables.global[name] = value; +function setGlobalVariable(name, value, args = {}) { + if (args.index !== undefined) { + try { + let globalVariable = JSON.parse(extension_settings.variables.global[name] ?? 'null'); + const numIndex = Number(args.index); + if (Number.isNaN(numIndex)) { + if (globalVariable === null) { + globalVariable = {}; + } + globalVariable[args.index] = value; + } else { + if (globalVariable === null) { + globalVariable = []; + } + globalVariable[numIndex] = value; + } + extension_settings.variables.global[name] = JSON.stringify(globalVariable); + } catch { + // that didn't work + } + } else { + extension_settings.variables.global[name] = value; + } saveSettingsDebounced(); } @@ -577,10 +619,10 @@ function lenValuesCallback(value) { export function registerVariableCommands() { registerSlashCommand('listvar', listVariablesCallback, [], ' – list registered chat variables', true, true); - registerSlashCommand('setvar', (args, value) => setLocalVariable(args.key || args.name, value), [], 'key=varname (value) – set a local variable value and pass it down the pipe, e.g. /setvar key=color green', true, true); + registerSlashCommand('setvar', (args, value) => setLocalVariable(args.key || args.name, value, args), [], 'key=varname (value) – set a local variable value and pass it down the pipe, e.g. /setvar key=color green', true, true); registerSlashCommand('getvar', (args, value) => getLocalVariable(value, args), [], 'index=listIndex (key) – get a local variable value and pass it down the pipe, index is optional, e.g. /getvar height or /getvar index=3 costumes', true, true); registerSlashCommand('addvar', (args, value) => addLocalVariable(args.key || args.name, value), [], 'key=varname (increment) – add a value to a local variable and pass the result down the pipe, e.g. /addvar score 10', true, true); - registerSlashCommand('setglobalvar', (args, value) => setGlobalVariable(args.key || args.name, value), [], 'key=varname (value) – set a global variable value and pass it down the pipe, e.g. /setglobalvar key=color green', true, true); + registerSlashCommand('setglobalvar', (args, value) => setGlobalVariable(args.key || args.name, value, args), [], 'key=varname (value) – set a global variable value and pass it down the pipe, e.g. /setglobalvar key=color green', true, true); registerSlashCommand('getglobalvar', (args, value) => getGlobalVariable(value, args), [], 'index=listIndex (key) – get a global variable value and pass it down the pipe, index is optional, e.g. /getglobalvar height or /getglobalvar index=3 costumes', true, true); registerSlashCommand('addglobalvar', (args, value) => addGlobalVariable(args.key || args.name, value), [], 'key=varname (increment) – add a value to a global variable and pass the result down the pipe, e.g. /addglobalvar score 10', true, true); registerSlashCommand('incvar', (_, value) => incrementLocalVariable(value), [], '(key) – increment a local variable by 1 and pass the result down the pipe, e.g. /incvar score', true, true); From 2ee57afe2a6267730d52ecb9a2431d4b381c7651 Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 16:51:45 +0000 Subject: [PATCH 2/8] add helpString for index in setvar --- public/scripts/variables.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/variables.js b/public/scripts/variables.js index 39038684a..03c405c68 100644 --- a/public/scripts/variables.js +++ b/public/scripts/variables.js @@ -619,10 +619,10 @@ function lenValuesCallback(value) { export function registerVariableCommands() { registerSlashCommand('listvar', listVariablesCallback, [], ' – list registered chat variables', true, true); - registerSlashCommand('setvar', (args, value) => setLocalVariable(args.key || args.name, value, args), [], 'key=varname (value) – set a local variable value and pass it down the pipe, e.g. /setvar key=color green', true, true); + registerSlashCommand('setvar', (args, value) => setLocalVariable(args.key || args.name, value, args), [], 'key=varname index=listIndex (value) – set a local variable value and pass it down the pipe, index is optional, e.g. /setvar key=color green', true, true); registerSlashCommand('getvar', (args, value) => getLocalVariable(value, args), [], 'index=listIndex (key) – get a local variable value and pass it down the pipe, index is optional, e.g. /getvar height or /getvar index=3 costumes', true, true); registerSlashCommand('addvar', (args, value) => addLocalVariable(args.key || args.name, value), [], 'key=varname (increment) – add a value to a local variable and pass the result down the pipe, e.g. /addvar score 10', true, true); - registerSlashCommand('setglobalvar', (args, value) => setGlobalVariable(args.key || args.name, value, args), [], 'key=varname (value) – set a global variable value and pass it down the pipe, e.g. /setglobalvar key=color green', true, true); + registerSlashCommand('setglobalvar', (args, value) => setGlobalVariable(args.key || args.name, value, args), [], 'key=varname index=listIndex (value) – set a global variable value and pass it down the pipe, index is optional, e.g. /setglobalvar key=color green', true, true); registerSlashCommand('getglobalvar', (args, value) => getGlobalVariable(value, args), [], 'index=listIndex (key) – get a global variable value and pass it down the pipe, index is optional, e.g. /getglobalvar height or /getglobalvar index=3 costumes', true, true); registerSlashCommand('addglobalvar', (args, value) => addGlobalVariable(args.key || args.name, value), [], 'key=varname (increment) – add a value to a global variable and pass the result down the pipe, e.g. /addglobalvar score 10', true, true); registerSlashCommand('incvar', (_, value) => incrementLocalVariable(value), [], '(key) – increment a local variable by 1 and pass the result down the pipe, e.g. /incvar score', true, true); From 7bfed3fca1944d5061f296f9a1a32bffc487a984 Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 18:12:05 +0000 Subject: [PATCH 3/8] /addvar on array to push --- public/scripts/variables.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/public/scripts/variables.js b/public/scripts/variables.js index 03c405c68..93e5d342a 100644 --- a/public/scripts/variables.js +++ b/public/scripts/variables.js @@ -109,6 +109,14 @@ function setGlobalVariable(name, value, args = {}) { function addLocalVariable(name, value) { const currentValue = getLocalVariable(name) || 0; + try { + const parsedValue = JSON.parse(currentValue); + if (typeof parsedValue == 'object' && parsedValue instanceof Array) { + parsedValue.push(value); + setGlobalVariable(name, JSON.stringify(parsedValue)); + return parsedValue; + } + } catch {} const increment = Number(value); if (isNaN(increment) || isNaN(Number(currentValue))) { @@ -129,6 +137,14 @@ function addLocalVariable(name, value) { function addGlobalVariable(name, value) { const currentValue = getGlobalVariable(name) || 0; + try { + const parsedValue = JSON.parse(currentValue); + if (typeof parsedValue == 'object' && parsedValue instanceof Array) { + parsedValue.push(value); + setGlobalVariable(name, JSON.stringify(parsedValue)); + return parsedValue; + } + } catch {} const increment = Number(value); if (isNaN(increment) || isNaN(Number(currentValue))) { From 5a719d635a387016223aeebe48a5ab19ee899052 Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 18:27:11 +0000 Subject: [PATCH 4/8] use isArray instead of instanceof --- public/scripts/variables.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/variables.js b/public/scripts/variables.js index 93e5d342a..a846aaeec 100644 --- a/public/scripts/variables.js +++ b/public/scripts/variables.js @@ -111,7 +111,7 @@ function addLocalVariable(name, value) { const currentValue = getLocalVariable(name) || 0; try { const parsedValue = JSON.parse(currentValue); - if (typeof parsedValue == 'object' && parsedValue instanceof Array) { + if (Array.isArray(parsedValue)) { parsedValue.push(value); setGlobalVariable(name, JSON.stringify(parsedValue)); return parsedValue; @@ -139,7 +139,7 @@ function addGlobalVariable(name, value) { const currentValue = getGlobalVariable(name) || 0; try { const parsedValue = JSON.parse(currentValue); - if (typeof parsedValue == 'object' && parsedValue instanceof Array) { + if (Array.isArray(parsedValue)) { parsedValue.push(value); setGlobalVariable(name, JSON.stringify(parsedValue)); return parsedValue; From d52b5fb9479aea2555849edb19d4c83aefd839ed Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 18:28:58 +0000 Subject: [PATCH 5/8] pass prev pipeResult through if result undefined --- public/scripts/slash-commands.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 4ff362e63..8588154c0 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -1524,7 +1524,11 @@ async function executeSlashCommands(text, unescape = false) { unnamedArg = unnamedArg.replace(/{{pipe}}/i, pipeResult || ''); } + let oldPipeResult = pipeResult; pipeResult = await result.command.callback(result.args, unnamedArg); + if (pipeResult === undefined && oldPipeResult !== undefined) { + pipeResult = oldPipeResult; + } if (result.command.interruptsGeneration) { interrupt = true; From 65f2cc1952b23501201463d1b523575f8067de39 Mon Sep 17 00:00:00 2001 From: LenAnderson Date: Thu, 7 Dec 2023 18:29:28 +0000 Subject: [PATCH 6/8] add a comment slash commend /# for commenting longer ST scripts --- public/scripts/slash-commands.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 8588154c0..5cf15ad89 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -166,6 +166,7 @@ parser.addCommand('memberdown', moveGroupMemberDownCallback, ['downmember'], '(message index or range) – shows a group member character card without switching chats', true, true); parser.addCommand('delswipe', deleteSwipeCallback, ['swipedel'], '(optional 1-based id) – deletes a swipe from the last chat message. If swipe id not provided - deletes the current swipe.', true, true); parser.addCommand('echo', echoCallback, [], '(title=string severity=info/warning/error/success [text]) – echoes the text to toast message. Useful for pipes debugging.', true, true); +parser.addCommand('#', (_, value) => undefined, [], ' – a comment, does nothing, e.g. /# the next three commands switch variables a and b', true, true); // '(text) – echoes the text to toast message. Useful for pipes debugging.', true, true); parser.addCommand('gen', generateCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating.', true, true); parser.addCommand('genraw', generateRawCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating. Does not include chat history or character card. Use instruct=off to skip instruct formatting, e.g. /genraw instruct=off Why is the sky blue?. Use stop=... with a JSON-serialized array to add one-time custom stop strings, e.g. /genraw stop=["\\n"] Say hi', true, true); From e2f886d796f2a70fefaefebd2d14901644ae3464 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:33:27 +0200 Subject: [PATCH 7/8] Revert pipe caching --- public/scripts/slash-commands.js | 7 +------ public/scripts/variables.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 5cf15ad89..31a1bba6c 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -166,8 +166,7 @@ parser.addCommand('memberdown', moveGroupMemberDownCallback, ['downmember'], '(message index or range) – shows a group member character card without switching chats', true, true); parser.addCommand('delswipe', deleteSwipeCallback, ['swipedel'], '(optional 1-based id) – deletes a swipe from the last chat message. If swipe id not provided - deletes the current swipe.', true, true); parser.addCommand('echo', echoCallback, [], '(title=string severity=info/warning/error/success [text]) – echoes the text to toast message. Useful for pipes debugging.', true, true); -parser.addCommand('#', (_, value) => undefined, [], ' – a comment, does nothing, e.g. /# the next three commands switch variables a and b', true, true); -// '(text) – echoes the text to toast message. Useful for pipes debugging.', true, true); +parser.addCommand('#', (_, value) => '', [], ' – a comment, does nothing, e.g. /# the next three commands switch variables a and b', true, true); parser.addCommand('gen', generateCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating.', true, true); parser.addCommand('genraw', generateRawCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating. Does not include chat history or character card. Use instruct=off to skip instruct formatting, e.g. /genraw instruct=off Why is the sky blue?. Use stop=... with a JSON-serialized array to add one-time custom stop strings, e.g. /genraw stop=["\\n"] Say hi', true, true); parser.addCommand('addswipe', addSwipeCallback, ['swipeadd'], '(text) – adds a swipe to the last chat message.', true, true); @@ -1525,11 +1524,7 @@ async function executeSlashCommands(text, unescape = false) { unnamedArg = unnamedArg.replace(/{{pipe}}/i, pipeResult || ''); } - let oldPipeResult = pipeResult; pipeResult = await result.command.callback(result.args, unnamedArg); - if (pipeResult === undefined && oldPipeResult !== undefined) { - pipeResult = oldPipeResult; - } if (result.command.interruptsGeneration) { interrupt = true; diff --git a/public/scripts/variables.js b/public/scripts/variables.js index a846aaeec..14020101b 100644 --- a/public/scripts/variables.js +++ b/public/scripts/variables.js @@ -43,7 +43,7 @@ function setLocalVariable(name, value, args = {}) { } localVariable[args.index] = value; } else { - if (localVariable === null) { + if (localVariable === null) { localVariable = []; } localVariable[numIndex] = value; @@ -92,7 +92,7 @@ function setGlobalVariable(name, value, args = {}) { } globalVariable[args.index] = value; } else { - if (globalVariable === null) { + if (globalVariable === null) { globalVariable = []; } globalVariable[numIndex] = value; @@ -116,7 +116,9 @@ function addLocalVariable(name, value) { setGlobalVariable(name, JSON.stringify(parsedValue)); return parsedValue; } - } catch {} + } catch { + // ignore non-array values + } const increment = Number(value); if (isNaN(increment) || isNaN(Number(currentValue))) { @@ -144,7 +146,9 @@ function addGlobalVariable(name, value) { setGlobalVariable(name, JSON.stringify(parsedValue)); return parsedValue; } - } catch {} + } catch { + // ignore non-array values + } const increment = Number(value); if (isNaN(increment) || isNaN(Number(currentValue))) { From 2607e787ff18413d40fb515f9545f466dc40236c Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:38:13 +0200 Subject: [PATCH 8/8] Put comment command on hold --- public/scripts/slash-commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 31a1bba6c..2ed1fbc47 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -166,7 +166,7 @@ parser.addCommand('memberdown', moveGroupMemberDownCallback, ['downmember'], '(message index or range) – shows a group member character card without switching chats', true, true); parser.addCommand('delswipe', deleteSwipeCallback, ['swipedel'], '(optional 1-based id) – deletes a swipe from the last chat message. If swipe id not provided - deletes the current swipe.', true, true); parser.addCommand('echo', echoCallback, [], '(title=string severity=info/warning/error/success [text]) – echoes the text to toast message. Useful for pipes debugging.', true, true); -parser.addCommand('#', (_, value) => '', [], ' – a comment, does nothing, e.g. /# the next three commands switch variables a and b', true, true); +//parser.addCommand('#', (_, value) => '', [], ' – a comment, does nothing, e.g. /# the next three commands switch variables a and b', true, true); parser.addCommand('gen', generateCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating.', true, true); parser.addCommand('genraw', generateRawCallback, [], '(lock=on/off [prompt]) – generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating. Does not include chat history or character card. Use instruct=off to skip instruct formatting, e.g. /genraw instruct=off Why is the sky blue?. Use stop=... with a JSON-serialized array to add one-time custom stop strings, e.g. /genraw stop=["\\n"] Say hi', true, true); parser.addCommand('addswipe', addSwipeCallback, ['swipeadd'], '(text) – adds a swipe to the last chat message.', true, true);