Merge pull request #3368 from SillyTavern/profile-stopstrings Add command and profile for custom stop strings

26feb448a3efe0673fbe1f82e490dd6efe93f781

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +45 -0Ignore whitespace
public/scripts/extensions/connection-manager/index.js+4 -0
@@ -30,6 +30,7 @@ const CC_COMMANDS = [
30 'api-url',30 'api-url',
31 'model',31 'model',
32 'proxy',32 'proxy',
33 'stop-strings',
33];34];
3435
35const TC_COMMANDS = [36const TC_COMMANDS = [
@@ -43,6 +44,7 @@ const TC_COMMANDS = [
43 'context',44 'context',
44 'instruct-state',45 'instruct-state',
45 'tokenizer',46 'tokenizer',
47 'stop-strings',
46];48];
4749
48const FANCY_NAMES = {50const FANCY_NAMES = {
@@ -57,6 +59,7 @@ const FANCY_NAMES = {
57 'instruct': 'Instruct Template',59 'instruct': 'Instruct Template',
58 'context': 'Context Template',60 'context': 'Context Template',
59 'tokenizer': 'Tokenizer',61 'tokenizer': 'Tokenizer',
62 'stop-strings': 'Custom Stopping Strings',
60};63};
6164
62/**65/**
@@ -138,6 +141,7 @@ const profilesProvider = () => [
138 * @property {string} [context] Context Template141 * @property {string} [context] Context Template
139 * @property {string} [instruct-state] Instruct Mode142 * @property {string} [instruct-state] Instruct Mode
140 * @property {string} [tokenizer] Tokenizer143 * @property {string} [tokenizer] Tokenizer
144 * @property {string} [stop-strings] Custom Stopping Strings
141 * @property {string[]} [exclude] Commands to exclude145 * @property {string[]} [exclude] Commands to exclude
142 */146 */
143147
public/scripts/power-user.js+41 -0
@@ -4072,4 +4072,45 @@ $(document).ready(() => {
4072 ],4072 ],
4073 helpString: 'activates a movingUI preset by name',4073 helpString: 'activates a movingUI preset by name',
4074 }));4074 }));
4075 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
4076 name: 'stop-strings',
4077 aliases: ['stopping-strings', 'custom-stopping-strings', 'custom-stop-strings'],
4078 helpString: `
4079 <div>
4080 Sets a list of custom stopping strings. Gets the list if no value is provided.
4081 </div>
4082 <div>
4083 <strong>Examples:</strong>
4084 </div>
4085 <ul>
4086 <li>Value must be a JSON-serialized array: <pre><code class="language-stscript">/stop-strings ["goodbye", "farewell"]</code></pre></li>
4087 <li>Pipe characters must be escaped with a backslash: <pre><code class="language-stscript">/stop-strings ["left\\|right"]</code></pre></li>
4088 </ul>
4089 `,
4090 returns: ARGUMENT_TYPE.LIST,
4091 unnamedArgumentList: [
4092 SlashCommandArgument.fromProps({
4093 description: 'list of strings',
4094 typeList: [ARGUMENT_TYPE.LIST],
4095 acceptsMultiple: false,
4096 isRequired: false,
4097 }),
4098 ],
4099 callback: (_, value) => {
4100 if (String(value ?? '').trim()) {
4101 const parsedValue = ((x) => { try { return JSON.parse(x.toString()); } catch { return null; } })(value);
4102 if (!parsedValue || !Array.isArray(parsedValue)) {
4103 throw new Error('Invalid list format. The value must be a JSON-serialized array of strings.');
4104 }
4105 parsedValue.forEach((item, index) => {
4106 parsedValue[index] = String(item);
4107 });
4108 power_user.custom_stopping_strings = JSON.stringify(parsedValue);
4109 $('#custom_stopping_strings').val(power_user.custom_stopping_strings);
4110 saveSettingsDebounced();
4111 }
4112
4113 return power_user.custom_stopping_strings;
4114 },
4115 }));
4075});4116});