Expand /persona-lock command for type - Add new main alias for /lock, renamed to /persona-lock - Allow no state to be provided to return the current lock state - Deprecate the old usage of /lock without state, without breaking it
| @@ -740,7 +740,7 @@ function isPersonaConnectionLocked(connection) { | ||
| 740 | 740 | * @param {PersonaLockType} type - Lock type |
| 741 | 741 | * @returns {boolean} Whether the persona is locked |
| 742 | 742 | */ |
| 743 | 743 | export function isPersonaLocked(type = 'chat') { |
| 744 | 744 | switch (type) { |
| 745 | 745 | case 'default': |
| 746 | 746 | return power_user.default_persona === user_avatar; |
| @@ -756,21 +756,26 @@ function isPersonaLocked(type = 'chat') { | ||
| 756 | 756 | /** |
| 757 | 757 | * Locks or unlocks the persona |
| 758 | 758 | * @param {boolean} state Desired lock state |
| 759 | + * @param {PersonaLockType} type - Lock type | |
| 759 | 760 | * @returns {Promise<void>} |
| 760 | 761 | */ |
| 761 | 762 | export async function setPersonaLockState(state, type = 'chat') { |
| 762 | 763 | return state ? await lockPersona(type) : await unlockPersona(type); |
| 763 | 764 | } |
| 764 | 765 | |
| 765 | 766 | /** |
| 766 | 767 | * Toggle the persona lock state |
| 767 | 768 | * @param {PersonaLockType} type - Lock type |
| 768 | 769 | * @returns {Promise<voidboolean>} - Whether the persona was locked |
| 769 | 770 | */ |
| 770 | 771 | export async function togglePersonaLock(type = 'chat') { |
| 771 | 772 | returnif (isPersonaLocked(type)) { |
| 772 | 773 | ? await unlockPersona(type); |
| 773 | - : await lockPersona(type); | |
| 774 | + return false; | |
| 775 | + } else { | |
| 776 | + await lockPersona(type); | |
| 777 | + return true; | |
| 778 | + } | |
| 774 | 779 | } |
| 775 | 780 | |
| 776 | 781 | /** |
| @@ -810,6 +815,8 @@ async function unlockPersona(type = 'chat') { | ||
| 810 | 815 | } |
| 811 | 816 | break; |
| 812 | 817 | } |
| 818 | + default: | |
| 819 | + throw new Error(`Unknown persona lock type: ${type}`); | |
| 813 | 820 | } |
| 814 | 821 | |
| 815 | 822 | updatePersonaLockIcons(); |
| @@ -889,6 +896,8 @@ async function lockPersona(type = 'chat') { | ||
| 889 | 896 | } |
| 890 | 897 | break; |
| 891 | 898 | } |
| 899 | + default: | |
| 900 | + throw new Error(`Unknown persona lock type: ${type}`); | |
| 892 | 901 | } |
| 893 | 902 | |
| 894 | 903 | updatePersonaLockIcons(); |
| @@ -54,7 +54,7 @@ import { getContext, saveMetadataDebounced } from './extensions.js'; | ||
| 54 | 54 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; |
| 55 | 55 | import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js'; |
| 56 | 56 | import { chat_completion_sources, oai_settings, promptManager } from './openai.js'; |
| 57 | 57 | import { autoSelectPersona, isPersonaLocked, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; |
| 58 | 58 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; |
| 59 | 59 | import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; |
| 60 | 60 | import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js'; |
| @@ -74,6 +74,7 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom | ||
| 74 | 74 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; |
| 75 | 75 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; |
| 76 | 76 | import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js'; |
| 77 | +import { t } from './i18n.js'; | |
| 77 | 78 | export { |
| 78 | 79 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, |
| 79 | 80 | }; |
| @@ -147,15 +148,62 @@ export function initDefaultSlashCommands() { | ||
| 147 | 148 | helpString: 'Syncs the user persona in user-attributed messages in the current chat.', |
| 148 | 149 | })); |
| 149 | 150 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 150 | 151 | name: 'persona-lock', |
| 151 | 152 | callback: lockPersonaCallback, |
| 153 | + returns: 'The current lock state for the given type', | |
| 154 | + helpString: 'Locks/unlocks a persona (name and avatar) to the current chat. Gets the current lock state for the given type if no state is provided.', | |
| 155 | + namedArgumentList: [ | |
| 156 | + SlashCommandNamedArgument.fromProps({ | |
| 157 | + name: 'type', | |
| 158 | + description: 'The type of the lock, where it should apply to', | |
| 159 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 160 | + defaultValue: 'chat', | |
| 161 | + enumList: [ | |
| 162 | + new SlashCommandEnumValue('chat', 'Lock the persona to the current chat.'), | |
| 163 | + new SlashCommandEnumValue('character', 'Lock this persona to the currently selected character. If the setting is enabled, mutliple personas can be locked to the same character.'), | |
| 164 | + new SlashCommandEnumValue('default', 'Lock this persona as the default persona for all new chats.'), | |
| 165 | + ], | |
| 166 | + }), | |
| 167 | + ], | |
| 168 | + unnamedArgumentList: [ | |
| 169 | + SlashCommandArgument.fromProps({ | |
| 170 | + description: 'state', | |
| 171 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 172 | + enumProvider: commonEnumProviders.boolean('onOffToggle'), | |
| 173 | + }), | |
| 174 | + ], | |
| 175 | + })); | |
| 176 | + // TODO: Legacy command. Might be removed in the future and replaced by /persona-lock with aliases. | |
| 177 | + SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |
| 178 | + name: 'lock', | |
| 179 | + callback: (args, value) => { | |
| 180 | + if (!value) { | |
| 181 | + value = 'toggle'; | |
| 182 | + toastr.warning(t`Using /lock without a provided state to toggle the persona is deprecated. Please use /persona-lock instead. | |
| 183 | + In the future this command with no state provided will return the current state, instead of toggling it.`, t`Deprecation Warning`); | |
| 184 | + } | |
| 185 | + return lockPersonaCallback(args, value); | |
| 186 | + }, | |
| 187 | + returns: 'The current lock state for the given type', | |
| 152 | 188 | aliases: ['bind'], |
| 153 | 189 | helpString: 'Locks/unlocks a persona (name and avatar) to the current chat. Gets the current lock state for the given type if no state is provided.', |
| 190 | + namedArgumentList: [ | |
| 191 | + SlashCommandNamedArgument.fromProps({ | |
| 192 | + name: 'type', | |
| 193 | + description: 'The type of the lock, where it should apply to', | |
| 194 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 195 | + defaultValue: 'chat', | |
| 196 | + enumList: [ | |
| 197 | + new SlashCommandEnumValue('chat', 'Lock the persona to the current chat.'), | |
| 198 | + new SlashCommandEnumValue('character', 'Lock this persona to the currently selected character. If the setting is enabled, mutliple personas can be locked to the same character.'), | |
| 199 | + new SlashCommandEnumValue('default', 'Lock this persona as the default persona for all new chats.'), | |
| 200 | + ], | |
| 201 | + }), | |
| 202 | + ], | |
| 154 | 203 | unnamedArgumentList: [ |
| 155 | 204 | SlashCommandArgument.fromProps({ |
| 156 | 205 | description: 'state', |
| 157 | 206 | typeList: [ARGUMENT_TYPE.STRING], |
| 158 | - isRequired: true, | |
| 159 | 207 | defaultValue: 'toggle', |
| 160 | 208 | enumProvider: commonEnumProviders.boolean('onOffToggle'), |
| 161 | 209 | }), |
| @@ -3346,19 +3394,25 @@ function syncCallback() { | ||
| 3346 | 3394 | } |
| 3347 | 3395 | |
| 3348 | 3396 | async function lockPersonaCallback(_args, value) { |
| 3349 | - if (['toggle', 't', ''].includes(value.trim().toLowerCase())) { | |
| 3397 | + const type = _args.type ?? 'chat'; | |
| 3350 | - await togglePersonaLock(); | |
| 3398 | + | |
| 3351 | - return ''; | |
| 3399 | + if (!value) { | |
| 3400 | + return String(isPersonaLocked(type)); | |
| 3401 | + } | |
| 3402 | + | |
| 3403 | + if (['toggle', 't'].includes(value.trim().toLowerCase())) { | |
| 3404 | + const result = await togglePersonaLock(type); | |
| 3405 | + return String(result); | |
| 3352 | 3406 | } |
| 3353 | 3407 | |
| 3354 | 3408 | if (isTrueBoolean(value)) { |
| 3355 | 3409 | await setPersonaLockState(true, type); |
| 3356 | 3410 | return 'true'; |
| 3357 | 3411 | } |
| 3358 | 3412 | |
| 3359 | 3413 | if (isFalseBoolean(value)) { |
| 3360 | 3414 | await setPersonaLockState(false, type); |
| 3361 | 3415 | return 'false'; |
| 3362 | 3416 | |
| 3363 | 3417 | } |
| 3364 | 3418 | |