Add slash commands and connection profiles support
| @@ -33,6 +33,8 @@ const CC_COMMANDS = [ | |||
| 33 | 33 | ||
| 34 | const TC_COMMANDS = [ | 34 | const TC_COMMANDS = [ |
| 35 | ...COMMON_COMMANDS, | 35 | ...COMMON_COMMANDS, |
| 36 | 'sysprompt', | ||
| 37 | 'sysprompt-state', | ||
| 36 | 'instruct', | 38 | 'instruct', |
| 37 | 'context', | 39 | 'context', |
| 38 | 'instruct-state', | 40 | 'instruct-state', |
| @@ -45,6 +47,8 @@ const FANCY_NAMES = { | |||
| 45 | 'preset': 'Settings Preset', | 47 | 'preset': 'Settings Preset', |
| 46 | 'model': 'Model', | 48 | 'model': 'Model', |
| 47 | 'proxy': 'Proxy Preset', | 49 | 'proxy': 'Proxy Preset', |
| 50 | 'sysprompt-state': 'Use System Prompt', | ||
| 51 | 'sysprompt': 'System Prompt Name', | ||
| 48 | 'instruct-state': 'Instruct Mode', | 52 | 'instruct-state': 'Instruct Mode', |
| 49 | 'instruct': 'Instruct Template', | 53 | 'instruct': 'Instruct Template', |
| 50 | 'context': 'Context Template', | 54 | 'context': 'Context Template', |
| @@ -180,6 +184,11 @@ async function readProfileFromCommands(mode, profile, cleanUp = false) { | |||
| 180 | } | 184 | } |
| 181 | 185 | ||
| 182 | if (cleanUp) { | 186 | if (cleanUp) { |
| 187 | for (const command of commands) { | ||
| 188 | if (command.endsWith('-state') && profile[command] === 'false') { | ||
| 189 | delete profile[command.replace('-state', '')]; | ||
| 190 | } | ||
| 191 | } | ||
| 183 | for (const command of opposingCommands) { | 192 | for (const command of opposingCommands) { |
| 184 | if (commands.includes(command)) { | 193 | if (commands.includes(command)) { |
| 185 | continue; | 194 | continue; |
| @@ -1,6 +1,11 @@ | |||
| 1 | import { saveSettingsDebounced } from '../script.js'; | 1 | import { saveSettingsDebounced } from '../script.js'; |
| 2 | import { power_user } from './power-user.js'; | 2 | import { power_user } from './power-user.js'; |
| 3 | import { resetScrollHeight } from './utils.js'; | 3 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 4 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; | ||
| 5 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; | ||
| 6 | import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; | ||
| 7 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; | ||
| 8 | import { isTrueBoolean, resetScrollHeight } from './utils.js'; | ||
| 4 | 9 | ||
| 5 | export let system_prompts = []; | 10 | export let system_prompts = []; |
| 6 | 11 | ||
| @@ -53,6 +58,57 @@ function toggleSyspromptDisabledControls() { | |||
| 53 | $contentBlock.toggleClass('disabled', !power_user.sysprompt.enabled); | 58 | $contentBlock.toggleClass('disabled', !power_user.sysprompt.enabled); |
| 54 | } | 59 | } |
| 55 | 60 | ||
| 61 | function enableSystemPromptCallback() { | ||
| 62 | power_user.sysprompt.enabled = true; | ||
| 63 | $enabled.prop('checked', true); | ||
| 64 | toggleSyspromptDisabledControls(); | ||
| 65 | saveSettingsDebounced(); | ||
| 66 | return ''; | ||
| 67 | } | ||
| 68 | |||
| 69 | function disableSystemPromptCallback() { | ||
| 70 | power_user.sysprompt.enabled = false; | ||
| 71 | $enabled.prop('checked', false); | ||
| 72 | toggleSyspromptDisabledControls(); | ||
| 73 | saveSettingsDebounced(); | ||
| 74 | return ''; | ||
| 75 | } | ||
| 76 | |||
| 77 | function toggleSystemPromptCallback(_args, state) { | ||
| 78 | if (!state || typeof state !== 'string') { | ||
| 79 | return String(power_user.sysprompt.enabled); | ||
| 80 | } | ||
| 81 | |||
| 82 | const newState = isTrueBoolean(state); | ||
| 83 | newState ? enableSystemPromptCallback() : disableSystemPromptCallback(); | ||
| 84 | return String(power_user.sysprompt.enabled); | ||
| 85 | } | ||
| 86 | |||
| 87 | function selectSystemPromptCallback(args, name) { | ||
| 88 | if (!power_user.sysprompt.enabled && !isTrueBoolean(args.forceGet)) { | ||
| 89 | return ''; | ||
| 90 | } | ||
| 91 | |||
| 92 | if (!name) { | ||
| 93 | return power_user.sysprompt.name; | ||
| 94 | } | ||
| 95 | |||
| 96 | const quiet = isTrueBoolean(args?.quiet); | ||
| 97 | const instructNames = system_prompts.map(preset => preset.name); | ||
| 98 | const fuse = new Fuse(instructNames); | ||
| 99 | const result = fuse.search(name); | ||
| 100 | |||
| 101 | if (result.length === 0) { | ||
| 102 | !quiet && toastr.warning(`System prompt "${name}" not found`); | ||
| 103 | return ''; | ||
| 104 | } | ||
| 105 | |||
| 106 | const foundName = result[0].item; | ||
| 107 | $select.val(foundName).trigger('input'); | ||
| 108 | !quiet && toastr.success(`System prompt "${foundName}" selected`); | ||
| 109 | return foundName; | ||
| 110 | } | ||
| 111 | |||
| 56 | jQuery(function () { | 112 | jQuery(function () { |
| 57 | $enabled.on('input', function () { | 113 | $enabled.on('input', function () { |
| 58 | power_user.sysprompt.enabled = !!$(this).prop('checked'); | 114 | power_user.sysprompt.enabled = !!$(this).prop('checked'); |
| @@ -61,6 +117,10 @@ jQuery(function () { | |||
| 61 | }); | 117 | }); |
| 62 | 118 | ||
| 63 | $select.on('input', async function () { | 119 | $select.on('input', async function () { |
| 120 | if (!power_user.sysprompt.enabled) { | ||
| 121 | $enabled.prop('checked', true).trigger('input'); | ||
| 122 | } | ||
| 123 | |||
| 64 | const name = String($(this).val()); | 124 | const name = String($(this).val()); |
| 65 | const prompt = system_prompts.find(p => p.name === name); | 125 | const prompt = system_prompts.find(p => p.name === name); |
| 66 | if (prompt) { | 126 | if (prompt) { |
| @@ -79,4 +139,73 @@ jQuery(function () { | |||
| 79 | power_user.sysprompt.content = String($(this).val()); | 139 | power_user.sysprompt.content = String($(this).val()); |
| 80 | saveSettingsDebounced(); | 140 | saveSettingsDebounced(); |
| 81 | }); | 141 | }); |
| 142 | |||
| 143 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 144 | name: 'sysprompt', | ||
| 145 | aliases: ['system-prompt'], | ||
| 146 | callback: selectSystemPromptCallback, | ||
| 147 | returns: 'current prompt name', | ||
| 148 | namedArgumentList: [ | ||
| 149 | SlashCommandNamedArgument.fromProps({ | ||
| 150 | name: 'quiet', | ||
| 151 | description: 'Suppress the toast message on prompt change', | ||
| 152 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 153 | defaultValue: 'false', | ||
| 154 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 155 | }), | ||
| 156 | SlashCommandNamedArgument.fromProps({ | ||
| 157 | name: 'forceGet', | ||
| 158 | description: 'Force getting a name even if system prompt is disabled', | ||
| 159 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 160 | defaultValue: 'false', | ||
| 161 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 162 | }), | ||
| 163 | ], | ||
| 164 | unnamedArgumentList: [ | ||
| 165 | SlashCommandArgument.fromProps({ | ||
| 166 | description: 'system prompt name', | ||
| 167 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 168 | enumProvider: () => system_prompts.map(x => new SlashCommandEnumValue(x.name, null, enumTypes.enum, enumIcons.preset)), | ||
| 169 | }), | ||
| 170 | ], | ||
| 171 | helpString: ` | ||
| 172 | <div> | ||
| 173 | Selects a system prompt by name. Enables the use of system prompt if not already enabled. | ||
| 174 | Gets the current system prompt if no name is provided and sysprompt is enabled or <code>forceGet=true</code> is passed. | ||
| 175 | </div> | ||
| 176 | <div> | ||
| 177 | <strong>Example:</strong> | ||
| 178 | <ul> | ||
| 179 | <li> | ||
| 180 | <pre><code class="language-stscript">/sysprompt </code></pre> | ||
| 181 | </li> | ||
| 182 | </ul> | ||
| 183 | </div> | ||
| 184 | `, | ||
| 185 | })); | ||
| 186 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 187 | name: 'sysprompt-on', | ||
| 188 | aliases: ['sysprompt-enable'], | ||
| 189 | callback: enableSystemPromptCallback, | ||
| 190 | helpString: 'Enables system prompt.', | ||
| 191 | })); | ||
| 192 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 193 | name: 'sysprompt-off', | ||
| 194 | aliases: ['sysprompt-disable'], | ||
| 195 | callback: disableSystemPromptCallback, | ||
| 196 | helpString: 'Disables system prompt', | ||
| 197 | })); | ||
| 198 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 199 | name: 'sysprompt-state', | ||
| 200 | aliases: ['sysprompt-toggle'], | ||
| 201 | helpString: 'Gets the current system prompt state. If an argument is provided, it will set the system prompt state.', | ||
| 202 | unnamedArgumentList: [ | ||
| 203 | SlashCommandArgument.fromProps({ | ||
| 204 | description: 'system prompt state', | ||
| 205 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 206 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 207 | }), | ||
| 208 | ], | ||
| 209 | callback: toggleSystemPromptCallback, | ||
| 210 | })); | ||
| 82 | }); | 211 | }); |