Add message-role command

1f0c0ccff4bf4fcec6a9685546bb86d5df25e87f

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

2 files changed, +97 -1Showing whitespace changes
public/scripts/slash-commands.js+91 -1
@@ -766,6 +766,48 @@ export function initDefaultSlashCommands() {
766 `,766 `,
767 }));767 }));
768 SlashCommandParser.addCommandObject(SlashCommand.fromProps({768 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
769 name: 'message-role',
770 callback: messageRoleCallback,
771 returns: 'The role of the message sender',
772 namedArgumentList: [
773 SlashCommandNamedArgument.fromProps({
774 name: 'at',
775 description: 'the ID of the message to modify (index-based, corresponding to message id). If omitted, the last message is chosen.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will modify the message right before the last message in chat. At must be nonzero.',
776 typeList: [ARGUMENT_TYPE.NUMBER],
777 defaultValue: '',
778 enumProvider: commonEnumProviders.messages({ allowIdAfter: true }),
779 }),
780 ],
781 unnamedArgumentList: [
782 SlashCommandArgument.fromProps({
783 description: 'Role to set for the message sender (user, assistant, system)',
784 typeList: [ARGUMENT_TYPE.STRING],
785 isRequired: false,
786 enumProvider: commonEnumProviders.messageRoles,
787 }),
788 ],
789 helpString: `
790 <div>
791 Changes the role of a message sender to one of your choice.
792 If no role is provided, just gets the current role of the message sender.
793 If no index is provided, the last message is chosen.
794 </div>
795 <div>
796 <strong>Example:</strong>
797 <ul>
798 <li>
799 <pre><code>/message-role | /echo</code></pre>
800 Will output the role of the sender of the last message.
801 </li>
802 <li>
803 <pre><code>/message-role at=-2 assistant</code></pre>
804 Will change the third message from the bottom to be sent by the assistant.
805 </li>
806 </ul>
807 </div>
808 `,
809 }));
810 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
769 name: 'message-name',811 name: 'message-name',
770 callback: messageNameCallback,812 callback: messageNameCallback,
771 returns: 'The name of the message sender',813 returns: 'The name of the message sender',
@@ -4562,13 +4604,61 @@ export function getNameAndAvatarForMessage(character, name = null) {
4562}4604}
45634605
4564/**4606/**
4607 * Changes the character role on a message at a given index.
4608 * @param {object?} args - Named arguments
4609 * @param {string} role - Role to change to.
4610 *
4611 * @returns {Promise<string>} The updated message role.
4612 */
4613async function messageRoleCallback(args, role) {
4614 let modifyAt = Number(args?.at ?? (chat.length - 1));
4615 // Convert possible depth parameter to index
4616 if (!isNaN(modifyAt) && (modifyAt < 0 || Object.is(modifyAt, -0))) {
4617 // Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7)
4618 modifyAt = chat.length + modifyAt;
4619 }
4620
4621 const message = chat[modifyAt];
4622 if (!message) {
4623 toastr.warning(t`No message found at the specified index.`);
4624 return '';
4625 }
4626
4627 role = String(role ?? '').trim().toLowerCase();
4628 if (!role || !['user', 'assistant', 'system'].includes(role)) {
4629 return message?.extra?.type === system_message_types.NARRATOR
4630 ? 'system'
4631 : message.is_user ? 'user' : 'assistant';
4632 }
4633
4634 message.extra = message.extra || {};
4635 if (role === 'system') {
4636 message.extra.type = system_message_types.NARRATOR;
4637 } else {
4638 delete message.extra.type;
4639 }
4640 message.is_user = role === 'user';
4641
4642 await eventSource.emit(event_types.MESSAGE_EDITED, modifyAt);
4643 const existingMessage = chatElement.find(`.mes[mesid="${modifyAt}"]`);
4644 if (existingMessage.length) {
4645 addOneMessage(message, { forceId: modifyAt, insertAfter: modifyAt, scroll: false });
4646 existingMessage.remove();
4647 }
4648 await eventSource.emit(event_types.MESSAGE_UPDATED, modifyAt);
4649 await saveChatConditional();
4650
4651 return role;
4652}
4653
4654/**
4565 * Changes the character name on a message at a given index.4655 * Changes the character name on a message at a given index.
4566 * @param {object?} args - Named arguments4656 * @param {object?} args - Named arguments
4567 * @param {string} name - Name to change to.4657 * @param {string} name - Name to change to.
4568 *4658 *
4569 * @returns {Promise<string>} The updated message name.4659 * @returns {Promise<string>} The updated message name.
4570 */4660 */
4571export async function messageNameCallback(args, name) {4661async function messageNameCallback(args, name) {
4572 let modifyAt = Number(args?.at ?? (chat.length - 1));4662 let modifyAt = Number(args?.at ?? (chat.length - 1));
4573 // Convert possible depth parameter to index4663 // Convert possible depth parameter to index
4574 if (!isNaN(modifyAt) && (modifyAt < 0 || Object.is(modifyAt, -0))) {4664 if (!isNaN(modifyAt) && (modifyAt < 0 || Object.is(modifyAt, -0))) {
public/scripts/slash-commands/SlashCommandCommonEnumsProvider.js+6 -0
@@ -329,4 +329,10 @@ export const commonEnumProviders = {
329 new SlashCommandEnumValue('null', null, enumTypes.type, enumIcons.null),329 new SlashCommandEnumValue('null', null, enumTypes.type, enumIcons.null),
330 new SlashCommandEnumValue('undefined', null, enumTypes.type, enumIcons.undefined),330 new SlashCommandEnumValue('undefined', null, enumTypes.type, enumIcons.undefined),
331 ],331 ],
332
333 messageRoles: () => [
334 new SlashCommandEnumValue('user', null, enumTypes.enum, enumIcons.user),
335 new SlashCommandEnumValue('assistant', null, enumTypes.enum, enumIcons.assistant),
336 new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.system),
337 ],
332};338};