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

745453264160344a2a52accdcad4c5afc71ec027

Wolfsblvt <wolfsblvt@gmail.com>

2 files changed, +81 -18Ignore whitespace
public/scripts/personas.js+16 -7
@@ -740,7 +740,7 @@ function isPersonaConnectionLocked(connection) {
740740 * @param {PersonaLockType} type - Lock type
741741 * @returns {boolean} Whether the persona is locked
742742 */
743743export function isPersonaLocked(type = 'chat') {
744744 switch (type) {
745745 case 'default':
746746 return power_user.default_persona === user_avatar;
@@ -756,21 +756,26 @@ function isPersonaLocked(type = 'chat') {
756756/**
757757 * Locks or unlocks the persona
758758 * @param {boolean} state Desired lock state
759+ * @param {PersonaLockType} type - Lock type
759760 * @returns {Promise<void>}
760761 */
761762export async function setPersonaLockState(state, type = 'chat') {
762763 return state ? await lockPersona(type) : await unlockPersona(type);
763764}
764765
765766/**
766767 * Toggle the persona lock state
767768 * @param {PersonaLockType} type - Lock type
768769 * @returns {Promise<voidboolean>} - Whether the persona was locked
769770 */
770771export async function togglePersonaLock(type = 'chat') {
771772 returnif (isPersonaLocked(type)) {
772773 ? await unlockPersona(type);
773- : await lockPersona(type);
774+ return false;
775+ } else {
776+ await lockPersona(type);
777+ return true;
778+ }
774779}
775780
776781/**
@@ -810,6 +815,8 @@ async function unlockPersona(type = 'chat') {
810815 }
811816 break;
812817 }
818+ default:
819+ throw new Error(`Unknown persona lock type: ${type}`);
813820 }
814821
815822 updatePersonaLockIcons();
@@ -889,6 +896,8 @@ async function lockPersona(type = 'chat') {
889896 }
890897 break;
891898 }
899+ default:
900+ throw new Error(`Unknown persona lock type: ${type}`);
892901 }
893902
894903 updatePersonaLockIcons();
public/scripts/slash-commands.js+65 -11
@@ -54,7 +54,7 @@ import { getContext, saveMetadataDebounced } from './extensions.js';
5454import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
5555import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
5656import { chat_completion_sources, oai_settings, promptManager } from './openai.js';
5757import { autoSelectPersona, isPersonaLocked, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js';
5858import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
5959import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
6060import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js';
@@ -74,6 +74,7 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom
7474import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js';
7575import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js';
7676import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js';
77+import { t } from './i18n.js';
7778export {
7879 executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
7980};
@@ -147,15 +148,62 @@ export function initDefaultSlashCommands() {
147148 helpString: 'Syncs the user persona in user-attributed messages in the current chat.',
148149 }));
149150 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
150151 name: 'persona-lock',
151152 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',
152188 aliases: ['bind'],
153189 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+ ],
154203 unnamedArgumentList: [
155204 SlashCommandArgument.fromProps({
156205 description: 'state',
157206 typeList: [ARGUMENT_TYPE.STRING],
158- isRequired: true,
159207 defaultValue: 'toggle',
160208 enumProvider: commonEnumProviders.boolean('onOffToggle'),
161209 }),
@@ -3346,19 +3394,25 @@ function syncCallback() {
33463394}
33473395
33483396async 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);
33523406 }
33533407
33543408 if (isTrueBoolean(value)) {
33553409 await setPersonaLockState(true, type);
33563410 return 'true';
33573411 }
33583412
33593413 if (isFalseBoolean(value)) {
33603414 await setPersonaLockState(false, type);
33613415 return 'false';
33623416
33633417 }
33643418