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 | * @param {PersonaLockType} type - Lock type | 740 | * @param {PersonaLockType} type - Lock type |
| 741 | * @returns {boolean} Whether the persona is locked | 741 | * @returns {boolean} Whether the persona is locked |
| 742 | */ | 742 | */ |
| 743 | function isPersonaLocked(type = 'chat') { | 743 | export function isPersonaLocked(type = 'chat') { |
| 744 | switch (type) { | 744 | switch (type) { |
| 745 | case 'default': | 745 | case 'default': |
| 746 | return power_user.default_persona === user_avatar; | 746 | return power_user.default_persona === user_avatar; |
| @@ -756,21 +756,26 @@ function isPersonaLocked(type = 'chat') { | |||
| 756 | /** | 756 | /** |
| 757 | * Locks or unlocks the persona | 757 | * Locks or unlocks the persona |
| 758 | * @param {boolean} state Desired lock state | 758 | * @param {boolean} state Desired lock state |
| 759 | * @param {PersonaLockType} type - Lock type | ||
| 759 | * @returns {Promise<void>} | 760 | * @returns {Promise<void>} |
| 760 | */ | 761 | */ |
| 761 | export async function setPersonaLockState(state) { | 762 | export async function setPersonaLockState(state, type = 'chat') { |
| 762 | return state ? await lockPersona() : await unlockPersona(); | 763 | return state ? await lockPersona(type) : await unlockPersona(type); |
| 763 | } | 764 | } |
| 764 | 765 | ||
| 765 | /** | 766 | /** |
| 766 | * Toggle the persona lock state | 767 | * Toggle the persona lock state |
| 767 | * @param {PersonaLockType} type - Lock type | 768 | * @param {PersonaLockType} type - Lock type |
| 768 | * @returns {Promise<void>} | 769 | * @returns {Promise<boolean>} - Whether the persona was locked |
| 769 | */ | 770 | */ |
| 770 | export async function togglePersonaLock(type = 'chat') { | 771 | export async function togglePersonaLock(type = 'chat') { |
| 771 | return isPersonaLocked(type) | 772 | if (isPersonaLocked(type)) { |
| 772 | ? await unlockPersona(type) | 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 | break; | 816 | break; |
| 812 | } | 817 | } |
| 818 | default: | ||
| 819 | throw new Error(`Unknown persona lock type: ${type}`); | ||
| 813 | } | 820 | } |
| 814 | 821 | ||
| 815 | updatePersonaLockIcons(); | 822 | updatePersonaLockIcons(); |
| @@ -889,6 +896,8 @@ async function lockPersona(type = 'chat') { | |||
| 889 | } | 896 | } |
| 890 | break; | 897 | break; |
| 891 | } | 898 | } |
| 899 | default: | ||
| 900 | throw new Error(`Unknown persona lock type: ${type}`); | ||
| 892 | } | 901 | } |
| 893 | 902 | ||
| 894 | updatePersonaLockIcons(); | 903 | updatePersonaLockIcons(); |
| @@ -54,7 +54,7 @@ import { getContext, saveMetadataDebounced } from './extensions.js'; | |||
| 54 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; | 54 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; |
| 55 | import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js'; | 55 | import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js'; |
| 56 | import { chat_completion_sources, oai_settings, promptManager } from './openai.js'; | 56 | import { chat_completion_sources, oai_settings, promptManager } from './openai.js'; |
| 57 | import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; | 57 | import { autoSelectPersona, isPersonaLocked, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; |
| 58 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; | 58 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; |
| 59 | import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; | 59 | import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; |
| 60 | import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js'; | 60 | import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js'; |
| @@ -74,6 +74,7 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom | |||
| 74 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; | 74 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; |
| 75 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; | 75 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; |
| 76 | import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js'; | 76 | import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js'; |
| 77 | import { t } from './i18n.js'; | ||
| 77 | export { | 78 | export { |
| 78 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, | 79 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, |
| 79 | }; | 80 | }; |
| @@ -147,15 +148,62 @@ export function initDefaultSlashCommands() { | |||
| 147 | helpString: 'Syncs the user persona in user-attributed messages in the current chat.', | 148 | helpString: 'Syncs the user persona in user-attributed messages in the current chat.', |
| 148 | })); | 149 | })); |
| 149 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 150 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 150 | name: 'lock', | 151 | name: 'persona-lock', |
| 151 | callback: lockPersonaCallback, | 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 | aliases: ['bind'], | 188 | aliases: ['bind'], |
| 153 | helpString: 'Locks/unlocks a persona (name and avatar) to the current chat', | 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 | unnamedArgumentList: [ | 203 | unnamedArgumentList: [ |
| 155 | SlashCommandArgument.fromProps({ | 204 | SlashCommandArgument.fromProps({ |
| 156 | description: 'state', | 205 | description: 'state', |
| 157 | typeList: [ARGUMENT_TYPE.STRING], | 206 | typeList: [ARGUMENT_TYPE.STRING], |
| 158 | isRequired: true, | ||
| 159 | defaultValue: 'toggle', | 207 | defaultValue: 'toggle', |
| 160 | enumProvider: commonEnumProviders.boolean('onOffToggle'), | 208 | enumProvider: commonEnumProviders.boolean('onOffToggle'), |
| 161 | }), | 209 | }), |
| @@ -3346,19 +3394,25 @@ function syncCallback() { | |||
| 3346 | } | 3394 | } |
| 3347 | 3395 | ||
| 3348 | async function lockPersonaCallback(_args, value) { | 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 | if (isTrueBoolean(value)) { | 3408 | if (isTrueBoolean(value)) { |
| 3355 | await setPersonaLockState(true); | 3409 | await setPersonaLockState(true, type); |
| 3356 | return ''; | 3410 | return 'true'; |
| 3357 | } | 3411 | } |
| 3358 | 3412 | ||
| 3359 | if (isFalseBoolean(value)) { | 3413 | if (isFalseBoolean(value)) { |
| 3360 | await setPersonaLockState(false); | 3414 | await setPersonaLockState(false, type); |
| 3361 | return ''; | 3415 | return 'false'; |
| 3362 | 3416 | ||
| 3363 | } | 3417 | } |
| 3364 | 3418 | ||