mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Even more enum refactorings (not done yet)
- Add common enum icons - enum def for existing enum types, with color description
This commit is contained in:
@ -235,6 +235,8 @@ import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
|
|||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
|
||||||
import { SlashCommandBrowser } from './scripts/slash-commands/SlashCommandBrowser.js';
|
import { SlashCommandBrowser } from './scripts/slash-commands/SlashCommandBrowser.js';
|
||||||
import { initCustomSelectedSamplers, validateDisabledSamplers } from './scripts/samplerSelect.js';
|
import { initCustomSelectedSamplers, validateDisabledSamplers } from './scripts/samplerSelect.js';
|
||||||
|
import { SlashCommandEnumValue, enumTypes } from './scripts/slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { enumIcons } from './scripts/slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
|
||||||
//exporting functions and vars for mods
|
//exporting functions and vars for mods
|
||||||
export {
|
export {
|
||||||
@ -8774,6 +8776,9 @@ jQuery(async function () {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect all unique API names in an array
|
||||||
|
const uniqueAPIs = [...new Set(Object.values(CONNECT_API_MAP).map(x => x.selected))];
|
||||||
|
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'dupe',
|
name: 'dupe',
|
||||||
callback: DupeChar,
|
callback: DupeChar,
|
||||||
@ -8790,7 +8795,9 @@ jQuery(async function () {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
null,
|
null,
|
||||||
Object.keys(CONNECT_API_MAP),
|
Object.entries(CONNECT_API_MAP).map(([api, { selected }]) =>
|
||||||
|
new SlashCommandEnumValue(api, selected, enumTypes.getBasedOnIndex(uniqueAPIs.findIndex(x => x === selected)),
|
||||||
|
selected[0].toUpperCase() ?? enumIcons.default)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -8882,9 +8889,11 @@ jQuery(async function () {
|
|||||||
returns: 'current preset',
|
returns: 'current preset',
|
||||||
namedArgumentList: [],
|
namedArgumentList: [],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'name', [ARGUMENT_TYPE.STRING], false,
|
description: 'instruct preset name',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
enumProvider: () => instruct_presets.map(preset => new SlashCommandEnumValue(preset.name, null, enumTypes.enum, enumIcons.preset)),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
<div>
|
<div>
|
||||||
@ -8915,9 +8924,11 @@ jQuery(async function () {
|
|||||||
callback: selectContextCallback,
|
callback: selectContextCallback,
|
||||||
returns: 'template name',
|
returns: 'template name',
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'name', [ARGUMENT_TYPE.STRING], false,
|
description: 'context preset name',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
enumProvider: () => context_presets.map(preset => new SlashCommandEnumValue(preset.name, null, enumTypes.enum, enumIcons.preset)),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Selects context template by name. Gets the current template if no name is provided',
|
helpString: 'Selects context template by name. Gets the current template if no name is provided',
|
||||||
}));
|
}));
|
||||||
|
@ -2,6 +2,10 @@ import { deleteAttachment, getDataBankAttachments, getDataBankAttachmentsForSour
|
|||||||
import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js';
|
import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js';
|
||||||
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||||
|
import { SlashCommandClosure } from '../../slash-commands/SlashCommandClosure.js';
|
||||||
|
import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { SlashCommandExecutor } from '../../slash-commands/SlashCommandExecutor.js';
|
||||||
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,6 +200,24 @@ jQuery(async () => {
|
|||||||
const buttons = await renderExtensionTemplateAsync('attachments', 'buttons', {});
|
const buttons = await renderExtensionTemplateAsync('attachments', 'buttons', {});
|
||||||
$('#extensionsMenu').prepend(buttons);
|
$('#extensionsMenu').prepend(buttons);
|
||||||
|
|
||||||
|
/** A collection of local enum providers for this context of data bank */
|
||||||
|
const localEnumProviders = {
|
||||||
|
/**
|
||||||
|
* All attachements in the data bank based on the source argument. If not provided, defaults to 'chat'.
|
||||||
|
* @param {'name' | 'url'} returnField - Whether the enum should return the 'name' field or the 'url'
|
||||||
|
* */
|
||||||
|
attachements: (returnField = 'name') => (/** @type {SlashCommandExecutor} */ executor) => {
|
||||||
|
const source = executor.namedArgumentList.find(it => it.name == 'source')?.value ?? 'chat';
|
||||||
|
if (source instanceof SlashCommandClosure) throw new Error('Argument \'source\' does not support closures');
|
||||||
|
const attachments = getAttachments(source);
|
||||||
|
|
||||||
|
return attachments.map(attachment => new SlashCommandEnumValue(
|
||||||
|
returnField === 'name' ? attachment.name : attachment.url,
|
||||||
|
`${extension_settings.disabled_attachments.includes(attachment.url) ? enumIcons.false : enumIcons.true} [${source}] ${returnField === 'url' ? attachment.name : attachment.url}`,
|
||||||
|
enumTypes.enum, enumIcons.file));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'db',
|
name: 'db',
|
||||||
callback: () => {
|
callback: () => {
|
||||||
@ -254,8 +276,18 @@ jQuery(async () => {
|
|||||||
helpString: 'Update an attachment in the Data Bank, preserving its name. Returns a new URL of the attachment.',
|
helpString: 'Update an attachment in the Data Bank, preserving its name. Returns a new URL of the attachment.',
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument('source', 'The source for the attachment.', ARGUMENT_TYPE.STRING, false, false, 'chat', TYPES),
|
new SlashCommandNamedArgument('source', 'The source for the attachment.', ARGUMENT_TYPE.STRING, false, false, 'chat', TYPES),
|
||||||
new SlashCommandNamedArgument('name', 'The name of the attachment.', ARGUMENT_TYPE.STRING, false, false),
|
SlashCommandNamedArgument.fromProps({
|
||||||
new SlashCommandNamedArgument('url', 'The URL of the attachment to update.', ARGUMENT_TYPE.STRING, false, false),
|
name: 'name',
|
||||||
|
description: 'The name of the attachment.',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
enumProvider: localEnumProviders.attachements('name'),
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'url',
|
||||||
|
description: 'The URL of the attachment.',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
enumProvider: localEnumProviders.attachements('url'),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument('The content of the file attachment.', ARGUMENT_TYPE.STRING, true, false),
|
new SlashCommandArgument('The content of the file attachment.', ARGUMENT_TYPE.STRING, true, false),
|
||||||
@ -272,7 +304,12 @@ jQuery(async () => {
|
|||||||
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, '', TYPES),
|
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, '', TYPES),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument('The name or URL of the attachment.', ARGUMENT_TYPE.STRING, true, false),
|
SlashCommandArgument.fromProps({
|
||||||
|
description: 'The name or URL of the attachment.',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: localEnumProviders.attachements(),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -285,7 +322,12 @@ jQuery(async () => {
|
|||||||
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, '', TYPES),
|
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, '', TYPES),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument('The name or URL of the attachment.', ARGUMENT_TYPE.STRING, true, false),
|
SlashCommandArgument.fromProps({
|
||||||
|
description: 'The name or URL of the attachment.',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: localEnumProviders.attachements(),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -298,7 +340,12 @@ jQuery(async () => {
|
|||||||
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, 'chat', TYPES),
|
new SlashCommandNamedArgument('source', 'The source of the attachment.', ARGUMENT_TYPE.STRING, false, false, 'chat', TYPES),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument('The name or URL of the attachment.', ARGUMENT_TYPE.STRING, true, false),
|
SlashCommandArgument.fromProps({
|
||||||
|
description: 'The name or URL of the attachment.',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: localEnumProviders.attachements(),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,7 @@ import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
|
|||||||
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||||
import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = 'caption';
|
const MODULE_NAME = 'caption';
|
||||||
@ -452,7 +453,7 @@ jQuery(async function () {
|
|||||||
name: 'id',
|
name: 'id',
|
||||||
description: 'get image from a message with this ID',
|
description: 'get image from a message with this ID',
|
||||||
typeList: [ARGUMENT_TYPE.NUMBER],
|
typeList: [ARGUMENT_TYPE.NUMBER],
|
||||||
enumProvider: () => getContext().chat.map((_, i) => new SlashCommandEnumValue(String(i), null, 'number', '1️⃣')),
|
enumProvider: commonEnumProviders.messages,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { SlashCommand } from '../../../slash-commands/SlashCommand.js';
|
import { SlashCommand } from '../../../slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../../slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../../slash-commands/SlashCommandArgument.js';
|
||||||
import { SlashCommandEnumValue } from '../../../slash-commands/SlashCommandEnumValue.js';
|
import { enumIcons } from '../../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { SlashCommandEnumValue, enumTypes } from '../../../slash-commands/SlashCommandEnumValue.js';
|
||||||
import { SlashCommandParser } from '../../../slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from '../../../slash-commands/SlashCommandParser.js';
|
||||||
import { isTrueBoolean } from '../../../utils.js';
|
import { isTrueBoolean } from '../../../utils.js';
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
@ -22,6 +23,28 @@ export class SlashCommandHandler {
|
|||||||
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
function getExecutionIcons(/**@type {QuickReply} */ qr) {
|
||||||
|
let icons = '';
|
||||||
|
if (qr.preventAutoExecute) icons += '🚫';
|
||||||
|
if (qr.isHidden) icons += '👁️';
|
||||||
|
if (qr.executeOnStartup) icons += '🚀';
|
||||||
|
if (qr.executeOnUser) icons += enumIcons.user;
|
||||||
|
if (qr.executeOnAi) icons += enumIcons.assistant;
|
||||||
|
if (qr.executeOnChatChange) icons += '💬';
|
||||||
|
if (qr.executeOnGroupMemberDraft) icons += enumIcons.group;
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
const localEnumProviders = {
|
||||||
|
qrSets: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, enumTypes.enum, 'S')),
|
||||||
|
|
||||||
|
qrEntries: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(qr => {
|
||||||
|
const icons = getExecutionIcons(qr);
|
||||||
|
const message = `${qr.automationId ? `[${qr.automationId}]` : ''}${icons ? `[auto: ${icons}]` : ''} ${qr.title || qr.message}`.trim();
|
||||||
|
return new SlashCommandEnumValue(qr.label, message, enumTypes.enum, 'QR');
|
||||||
|
}) ?? [],
|
||||||
|
}
|
||||||
|
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'qr',
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'qr',
|
||||||
callback: (_, value) => this.executeQuickReplyByIndex(Number(value)),
|
callback: (_, value) => this.executeQuickReplyByIndex(Number(value)),
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -53,7 +76,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Toggle global QR set',
|
helpString: 'Toggle global QR set',
|
||||||
@ -73,7 +96,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Activate global QR set',
|
helpString: 'Activate global QR set',
|
||||||
@ -88,7 +111,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Deactivate global QR set',
|
helpString: 'Deactivate global QR set',
|
||||||
@ -108,7 +131,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Toggle chat QR set',
|
helpString: 'Toggle chat QR set',
|
||||||
@ -121,7 +144,7 @@ export class SlashCommandHandler {
|
|||||||
},
|
},
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'visible', 'whether the QR set should be visible', [ARGUMENT_TYPE.BOOLEAN], false, false, 'true', ['true', 'false'],
|
'visible', 'whether the QR set should be visible', [ARGUMENT_TYPE.BOOLEAN], false, false, 'true',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -129,7 +152,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Activate chat QR set',
|
helpString: 'Activate chat QR set',
|
||||||
@ -144,7 +167,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Deactivate chat QR set',
|
helpString: 'Deactivate chat QR set',
|
||||||
@ -171,7 +194,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Gets a list of the names of all quick replies in this quick reply set.',
|
helpString: 'Gets a list of the names of all quick replies in this quick reply set.',
|
||||||
@ -250,13 +273,13 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'label',
|
name: 'label',
|
||||||
description: 'Quick Reply label',
|
description: 'Quick Reply label',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(x => new SlashCommandEnumValue(x.label, null, 'qr-entry')),
|
enumProvider: localEnumProviders.qrEntries,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Deletes a Quick Reply from the specified set. If no label is provided, the entire set is deleted.',
|
helpString: 'Deletes a Quick Reply from the specified set. If no label is provided, the entire set is deleted.',
|
||||||
@ -272,13 +295,13 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'label',
|
name: 'label',
|
||||||
description: 'Quick Reply label',
|
description: 'Quick Reply label',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(x => new SlashCommandEnumValue(x.label, null, 'qr-entry')),
|
enumProvider: localEnumProviders.qrEntries,
|
||||||
}),
|
}),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'chain', 'boolean', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
'chain', 'boolean', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
||||||
@ -289,7 +312,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -317,13 +340,13 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'label',
|
name: 'label',
|
||||||
description: 'Quick Reply label',
|
description: 'Quick Reply label',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(x => new SlashCommandEnumValue(x.label, null, 'qr-entry')),
|
enumProvider: localEnumProviders.qrEntries,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -331,7 +354,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -359,14 +382,14 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
SlashCommandArgument.fromProps({
|
SlashCommandArgument.fromProps({
|
||||||
description: 'Quick Reply label',
|
description: 'Quick Reply label',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(x => new SlashCommandEnumValue(x.label, null, 'qr-entry')),
|
enumProvider: localEnumProviders.qrEntries,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -401,7 +424,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -431,7 +454,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -455,7 +478,7 @@ export class SlashCommandHandler {
|
|||||||
description: 'QR set name',
|
description: 'QR set name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => QuickReplySet.list.map(qrSet => new SlashCommandEnumValue(qrSet.name, null, 'qr-set', 'QR')),
|
enumProvider: localEnumProviders.qrSets,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
|
@ -31,7 +31,7 @@ import { SlashCommand } from '../../slash-commands/SlashCommand.js';
|
|||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
|
||||||
import { resolveVariable } from '../../variables.js';
|
import { resolveVariable } from '../../variables.js';
|
||||||
import { debounce_timeout } from '../../constants.js';
|
import { debounce_timeout } from '../../constants.js';
|
||||||
import { commonEnumProviders, getEnumBooleanValues } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
@ -3347,7 +3347,7 @@ jQuery(async () => {
|
|||||||
name: 'negative',
|
name: 'negative',
|
||||||
description: 'negative prompt prefix',
|
description: 'negative prompt prefix',
|
||||||
typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.VARIABLE_NAME],
|
typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
enumProvider: () => [...getEnumBooleanValues(), ...commonEnumProviders.variables('all')()],
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
|
@ -230,6 +230,17 @@ export async function getGroupChat(groupId, reload = false) {
|
|||||||
await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
|
await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the members of a group
|
||||||
|
*
|
||||||
|
* @param {string} [groupId=selected_group] - The ID of the group to retrieve members from. Defaults to the currently selected group.
|
||||||
|
* @returns {import('../script.js').Character[]} An array of character objects representing the members of the group. If the group is not found, an empty array is returned.
|
||||||
|
*/
|
||||||
|
export function getGroupMembers(groupId = selected_group) {
|
||||||
|
const group = groups.find((x) => x.id === groupId);
|
||||||
|
return group?.members.map(member => characters.find(x => x.avatar === member)) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the character ID for a group member.
|
* Finds the character ID for a group member.
|
||||||
* @param {string} arg 1-based member index or character name
|
* @param {string} arg 1-based member index or character name
|
||||||
|
@ -4609,7 +4609,7 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
description: 'name',
|
description: 'name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => proxies.map(preset => new SlashCommandEnumValue(preset.name)),
|
enumProvider: () => proxies.map(preset => new SlashCommandEnumValue(preset.name, preset.url)),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Sets a proxy preset by name.',
|
helpString: 'Sets a proxy preset by name.',
|
||||||
|
@ -46,7 +46,8 @@ import { PARSER_FLAG, SlashCommandParser } from './slash-commands/SlashCommandPa
|
|||||||
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
|
||||||
import { AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js';
|
import { AUTOCOMPLETE_WIDTH } from './autocomplete/AutoComplete.js';
|
||||||
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
loadPowerUserSettings,
|
loadPowerUserSettings,
|
||||||
@ -3890,7 +3891,7 @@ $(document).ready(() => {
|
|||||||
SlashCommandArgument.fromProps({
|
SlashCommandArgument.fromProps({
|
||||||
description: 'optional tag name',
|
description: 'optional tag name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: () => tags.filter(tag => Object.values(tag_map).some(x => x.includes(tag.id))).map(tag => new SlashCommandEnumValue(tag.name)),
|
enumProvider: () => tags.filter(tag => Object.values(tag_map).some(x => x.includes(tag.id))).map(tag => new SlashCommandEnumValue(tag.name, null, enumTypes.enum, enumIcons.tag)),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Start a new chat with a random character. If an argument is provided, only considers characters that have the specified tag.',
|
helpString: 'Start a new chat with a random character. If an argument is provided, only considers characters that have the specified tag.',
|
||||||
|
@ -22,7 +22,8 @@ import { kai_settings } from './kai-settings.js';
|
|||||||
import { context_presets, getContextSettings, power_user } from './power-user.js';
|
import { context_presets, getContextSettings, power_user } from './power-user.js';
|
||||||
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashCommandArgument.js';
|
||||||
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
||||||
import {
|
import {
|
||||||
textgenerationwebui_preset_names,
|
textgenerationwebui_preset_names,
|
||||||
@ -485,7 +486,7 @@ export async function initPresetManager() {
|
|||||||
SlashCommandArgument.fromProps({
|
SlashCommandArgument.fromProps({
|
||||||
description: 'name',
|
description: 'name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
enumProvider: () => getPresetManager().getAllPresets().map(preset => new SlashCommandEnumValue(preset)),
|
enumProvider: () => getPresetManager().getAllPresets().map(preset => new SlashCommandEnumValue(preset, null, enumTypes.enum, enumIcons.preset)),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
|
@ -433,6 +433,23 @@ class FandomScraper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const iso6391Codes = ["aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az",
|
||||||
|
"ba", "be", "bg", "bh", "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce",
|
||||||
|
"ch", "co", "cr", "cs", "cu", "cv", "cy", "da", "de", "dv", "dz", "ee",
|
||||||
|
"el", "en", "eo", "es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr",
|
||||||
|
"fy", "ga", "gd", "gl", "gn", "gu", "gv", "ha", "he", "hi", "ho", "hr",
|
||||||
|
"ht", "hu", "hy", "hz", "ia", "id", "ie", "ig", "ii", "ik", "io", "is",
|
||||||
|
"it", "iu", "ja", "jv", "ka", "kg", "ki", "kj", "kk", "kl", "km", "kn",
|
||||||
|
"ko", "kr", "ks", "ku", "kv", "kw", "ky", "la", "lb", "lg", "li", "ln",
|
||||||
|
"lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk", "ml", "mn", "mr", "ms",
|
||||||
|
"mt", "my", "na", "nb", "nd", "ne", "ng", "nl", "nn", "no", "nr", "nv",
|
||||||
|
"ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl", "ps", "pt", "qu",
|
||||||
|
"rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si", "sk",
|
||||||
|
"sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta",
|
||||||
|
"te", "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw",
|
||||||
|
"ty", "ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh", "yi",
|
||||||
|
"yo", "za", "zh", "zu"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrape transcript from a YouTube video.
|
* Scrape transcript from a YouTube video.
|
||||||
* @implements {Scraper}
|
* @implements {Scraper}
|
||||||
@ -464,7 +481,7 @@ class YouTubeScraper {
|
|||||||
helpString: 'Scrape a transcript from a YouTube video by ID or URL.',
|
helpString: 'Scrape a transcript from a YouTube video by ID or URL.',
|
||||||
returns: ARGUMENT_TYPE.STRING,
|
returns: ARGUMENT_TYPE.STRING,
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument('lang', 'ISO 639-1 language code of the transcript, e.g. "en"', ARGUMENT_TYPE.STRING, false, false, ''),
|
new SlashCommandNamedArgument('lang', 'ISO 639-1 language code of the transcript, e.g. "en"', ARGUMENT_TYPE.STRING, false, false, '', iso6391Codes),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument('URL or ID of the YouTube video', ARGUMENT_TYPE.STRING, true, false),
|
new SlashCommandArgument('URL or ID of the YouTube video', ARGUMENT_TYPE.STRING, true, false),
|
||||||
|
@ -44,7 +44,7 @@ import { getMessageTimeStamp } from './RossAscends-mods.js';
|
|||||||
import { hideChatMessageRange } from './chats.js';
|
import { hideChatMessageRange } from './chats.js';
|
||||||
import { extension_settings, getContext, saveMetadataDebounced } from './extensions.js';
|
import { extension_settings, getContext, saveMetadataDebounced } from './extensions.js';
|
||||||
import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
|
import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
|
||||||
import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
|
import { findGroupMemberId, getGroupMembers, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
|
||||||
import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';
|
import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';
|
||||||
import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, user_avatar } from './personas.js';
|
import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, user_avatar } from './personas.js';
|
||||||
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
||||||
@ -62,6 +62,7 @@ import { SlashCommand } from './slash-commands/SlashCommand.js';
|
|||||||
import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js';
|
import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js';
|
||||||
import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js';
|
import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashCommandNamedArgumentAssignment.js';
|
||||||
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
|
import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
export {
|
export {
|
||||||
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
||||||
};
|
};
|
||||||
@ -148,12 +149,14 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
'name', 'Character name', [ARGUMENT_TYPE.STRING], true,
|
'name', 'Character name', [ARGUMENT_TYPE.STRING], true,
|
||||||
),
|
),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'compact', 'Use compact layout', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', ['true', 'false'],
|
'compact', 'Use compact layout', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
||||||
),
|
),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'at',
|
name: 'at',
|
||||||
description: 'position to insert the message',
|
description: 'position to insert the message',
|
||||||
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -196,6 +199,8 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
name: 'at',
|
name: 'at',
|
||||||
description: 'position to insert the message',
|
description: 'position to insert the message',
|
||||||
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -249,6 +254,8 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
name: 'at',
|
name: 'at',
|
||||||
description: 'position to insert the message',
|
description: 'position to insert the message',
|
||||||
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -332,10 +339,7 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
description: 'name',
|
description: 'name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => [
|
enumProvider: commonEnumProviders.charName('all'),
|
||||||
...characters.map(it => new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
|
|
||||||
...groups.map(it => new SlashCommandEnumValue(it.name, null, 'variable', 'G')),
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Opens up a chat with the character or group by its name',
|
helpString: 'Opens up a chat with the character or group by its name',
|
||||||
@ -383,7 +387,7 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
description: 'character name',
|
description: 'character name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: () => characters.map(it => new SlashCommandEnumValue(it.name, null, 'qr', 'C')),
|
enumProvider: commonEnumProviders.charName('all'),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -398,9 +402,12 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
callback: deleteMessagesByNameCallback,
|
callback: deleteMessagesByNameCallback,
|
||||||
namedArgumentList: [],
|
namedArgumentList: [],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'name', [ARGUMENT_TYPE.STRING], true,
|
description: 'name',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: commonEnumProviders.charName('all'),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
aliases: ['cancel'],
|
aliases: ['cancel'],
|
||||||
helpString: `
|
helpString: `
|
||||||
@ -433,6 +440,8 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
name: 'at',
|
name: 'at',
|
||||||
description: 'position to insert the message',
|
description: 'position to insert the message',
|
||||||
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
}),
|
}),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'name',
|
'name',
|
||||||
@ -499,9 +508,12 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
name: 'hide',
|
name: 'hide',
|
||||||
callback: hideMessageCallback,
|
callback: hideMessageCallback,
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'message index or range', [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], true,
|
description: 'message index or range',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: () => chat.map((_, i) => new SlashCommandEnumValue(String(i), null, 'number', '1️⃣')),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Hides a chat message from the prompt.',
|
helpString: 'Hides a chat message from the prompt.',
|
||||||
}));
|
}));
|
||||||
@ -520,9 +532,14 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
callback: disableGroupMemberCallback,
|
callback: disableGroupMemberCallback,
|
||||||
aliases: ['disable', 'disablemember', 'memberdisable'],
|
aliases: ['disable', 'disablemember', 'memberdisable'],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'member index or name', [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], true,
|
description: 'member index or name',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: () => [
|
||||||
|
...getGroupMembers().map((character, i) => new SlashCommandEnumValue(String(i), character.name, 'name', '👤')),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
helpString: 'Disables a group member from being drafted for replies.',
|
helpString: 'Disables a group member from being drafted for replies.',
|
||||||
}));
|
}));
|
||||||
@ -791,7 +808,6 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
|||||||
description: 'Whether to suppress the toast message notifying about the /abort call.',
|
description: 'Whether to suppress the toast message notifying about the /abort call.',
|
||||||
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
||||||
defaultValue: 'true',
|
defaultValue: 'true',
|
||||||
enumList: ['true', 'false'],
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
@ -1606,6 +1622,7 @@ async function runCallback(args, name) {
|
|||||||
*/
|
*/
|
||||||
function abortCallback({ _abortController, quiet }, reason) {
|
function abortCallback({ _abortController, quiet }, reason) {
|
||||||
_abortController.abort((reason ?? '').toString().length == 0 ? '/abort command executed' : reason, !isFalseBoolean(quiet ?? 'true'));
|
_abortController.abort((reason ?? '').toString().length == 0 ? '/abort command executed' : reason, !isFalseBoolean(quiet ?? 'true'));
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function delayCallback(_, amount) {
|
async function delayCallback(_, amount) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SlashCommandClosure } from './SlashCommandClosure.js';
|
import { SlashCommandClosure } from './SlashCommandClosure.js';
|
||||||
import { getEnumBooleanValues, getEnumIconByValueType } from './SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js';
|
||||||
import { SlashCommandEnumValue } from './SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from './SlashCommandEnumValue.js';
|
||||||
import { SlashCommandExecutor } from './SlashCommandExecutor.js';
|
import { SlashCommandExecutor } from './SlashCommandExecutor.js';
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ export class SlashCommandArgument {
|
|||||||
this.forceEnum = forceEnum;
|
this.forceEnum = forceEnum;
|
||||||
|
|
||||||
// If no enums were set explictly and the type is one where we know possible enum values, we set them here
|
// If no enums were set explictly and the type is one where we know possible enum values, we set them here
|
||||||
if (!this.enumList.length && types == ARGUMENT_TYPE.BOOLEAN) this.enumList = getEnumBooleanValues();
|
if (!this.enumList.length && types == ARGUMENT_TYPE.BOOLEAN) this.enumList = commonEnumProviders.boolean()();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,105 @@
|
|||||||
import { chat_metadata, characters, substituteParams } from "../../script.js";
|
import { chat_metadata, characters, substituteParams, chat, extension_prompt_roles } from "../../script.js";
|
||||||
import { extension_settings } from "../extensions.js";
|
import { extension_settings } from "../extensions.js";
|
||||||
import { groups } from "../group-chats.js";
|
import { groups } from "../group-chats.js";
|
||||||
import { searchCharByName, getTagsList, tags } from "../tags.js";
|
import { searchCharByName, getTagsList, tags } from "../tags.js";
|
||||||
import { SlashCommandEnumValue } from "./SlashCommandEnumValue.js";
|
import { SlashCommandClosure } from "./SlashCommandClosure.js";
|
||||||
|
import { SlashCommandEnumValue, enumTypes } from "./SlashCommandEnumValue.js";
|
||||||
import { SlashCommandExecutor } from "./SlashCommandExecutor.js";
|
import { SlashCommandExecutor } from "./SlashCommandExecutor.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of regularly used enum icons
|
||||||
|
*/
|
||||||
|
export const enumIcons = {
|
||||||
|
default: '◊',
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
variable: 'V',
|
||||||
|
localVariable: 'L',
|
||||||
|
globalVariable: 'G',
|
||||||
|
scopeVariable: 'S',
|
||||||
|
|
||||||
|
// Common types
|
||||||
|
character: '👤',
|
||||||
|
group: '🧑🤝🧑',
|
||||||
|
qr: '🤖',
|
||||||
|
tag: '🏷️',
|
||||||
|
world: '🌐',
|
||||||
|
preset: '⚙️',
|
||||||
|
file: '📄',
|
||||||
|
|
||||||
|
true: '✔️',
|
||||||
|
false: '❌',
|
||||||
|
|
||||||
|
// Value types
|
||||||
|
boolean: '🔲',
|
||||||
|
string: '📝',
|
||||||
|
number: '1️⃣',
|
||||||
|
array: '📦',
|
||||||
|
enum: '📚',
|
||||||
|
dictionary: '📖',
|
||||||
|
closure: '🧩',
|
||||||
|
|
||||||
|
// Roles
|
||||||
|
system: '⚙️',
|
||||||
|
user: '👤',
|
||||||
|
assistant: '🤖',
|
||||||
|
|
||||||
|
// WI Icons
|
||||||
|
constant: '🔵',
|
||||||
|
normal: '🟢',
|
||||||
|
disabled: '❌',
|
||||||
|
vectorized: '🔗',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the appropriate WI icon based on the entry
|
||||||
|
*
|
||||||
|
* @param {Object} entry - WI entry
|
||||||
|
* @returns {string} The corresponding WI icon
|
||||||
|
*/
|
||||||
|
getWiStatusIcon: (entry) => {
|
||||||
|
if (entry.constant) return enumIcons.constant;
|
||||||
|
if (entry.disable) return enumIcons.disabled;
|
||||||
|
if (entry.vectorized) return enumIcons.vectorized;
|
||||||
|
return enumIcons.normal;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the appropriate icon based on the role
|
||||||
|
*
|
||||||
|
* @param {extension_prompt_roles} role - The role to get the icon for
|
||||||
|
* @returns {string} The corresponding icon
|
||||||
|
*/
|
||||||
|
getRoleIcon: (role) => {
|
||||||
|
switch (role) {
|
||||||
|
case extension_prompt_roles.SYSTEM: return enumIcons.system;
|
||||||
|
case extension_prompt_roles.USER: return enumIcons.user;
|
||||||
|
case extension_prompt_roles.ASSISTANT: return enumIcons.assistant;
|
||||||
|
default: return enumIcons.default;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of common enum providers
|
* A collection of common enum providers
|
||||||
*
|
*
|
||||||
* Can be used on `SlashCommandNamedArgument` and `SlashCommandArgument` and their `enumProvider` property.
|
* Can be used on `SlashCommandNamedArgument` and `SlashCommandArgument` and their `enumProvider` property.
|
||||||
*/
|
*/
|
||||||
export const commonEnumProviders = {
|
export const commonEnumProviders = {
|
||||||
|
/**
|
||||||
|
* Enum values for booleans. Either using true/false or on/off
|
||||||
|
* Optionally supports "toggle".
|
||||||
|
* @param {('onOff'|'onOffToggle'|'trueFalse')?} [mode='trueFalse'] - The mode to use. Default is 'trueFalse'.
|
||||||
|
* @returns {() => SlashCommandEnumValue[]}
|
||||||
|
*/
|
||||||
|
boolean: (mode = 'trueFalse') => () => {
|
||||||
|
switch (mode) {
|
||||||
|
case 'onOff': return [new SlashCommandEnumValue('on', null, 'macro', enumIcons.true), new SlashCommandEnumValue('off', null, 'macro', enumIcons.false)];
|
||||||
|
case 'onOffToggle': return [new SlashCommandEnumValue('on', null, 'macro', enumIcons.true), new SlashCommandEnumValue('off', null, 'macro', enumIcons.false), new SlashCommandEnumValue('toggle', null, 'macro', enumIcons.boolean)];
|
||||||
|
case 'trueFalse': return [new SlashCommandEnumValue('true', null, 'macro', enumIcons.true), new SlashCommandEnumValue('false', null, 'macro', enumIcons.false)];
|
||||||
|
default: throw new Error(`Invalid boolean enum provider mode: ${mode}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All possible variable names
|
* All possible variable names
|
||||||
*
|
*
|
||||||
@ -23,9 +112,9 @@ export const commonEnumProviders = {
|
|||||||
const types = type.flat();
|
const types = type.flat();
|
||||||
const isAll = types.includes('all');
|
const isAll = types.includes('all');
|
||||||
return [
|
return [
|
||||||
...isAll || types.includes('global') ? Object.keys(chat_metadata.variables).map(x => new SlashCommandEnumValue(x, null, 'variable', 'L')) : [],
|
...isAll || types.includes('global') ? Object.keys(extension_settings.variables.global ?? []).map(x => new SlashCommandEnumValue(x, null, enumTypes.macro, enumIcons.globalVariable)) : [],
|
||||||
...isAll || types.includes('local') ? Object.keys(extension_settings.variables.global).map(x => new SlashCommandEnumValue(x, null, 'variable', 'G')) : [],
|
...isAll || types.includes('local') ? Object.keys(chat_metadata.variables ?? []).map(x => new SlashCommandEnumValue(x, null, enumTypes.name, enumIcons.localVariable)) : [],
|
||||||
...isAll || types.includes('scope') ? [].map(x => new SlashCommandEnumValue(x, null, 'variable', 'S')) : [], // TODO: Add scoped variables here, Lenny
|
...isAll || types.includes('scope') ? [].map(x => new SlashCommandEnumValue(x, null, enumTypes.variable, enumIcons.scopeVariable)) : [], // TODO: Add scoped variables here, Lenny
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -35,11 +124,10 @@ export const commonEnumProviders = {
|
|||||||
* @param {('all' | 'character' | 'group')?} [mode='all'] - Which type to return
|
* @param {('all' | 'character' | 'group')?} [mode='all'] - Which type to return
|
||||||
* @returns {() => SlashCommandEnumValue[]}
|
* @returns {() => SlashCommandEnumValue[]}
|
||||||
*/
|
*/
|
||||||
charName: (mode) => () => {
|
charName: (mode = 'all') => () => {
|
||||||
mode = mode ?? 'all';
|
|
||||||
return [
|
return [
|
||||||
...['all', 'character'].includes(mode) ? characters.map(it => new SlashCommandEnumValue(it.name, null, 'qr', 'C')) : [],
|
...['all', 'character'].includes(mode) ? characters.map(it => new SlashCommandEnumValue(it.name, null, enumTypes.name, enumIcons.character)) : [],
|
||||||
...['all', 'group'].includes(mode) ? groups.map(it => new SlashCommandEnumValue(it.name, null, 'variable', 'G')) : [],
|
...['all', 'group'].includes(mode) ? groups.map(it => new SlashCommandEnumValue(it.name, null, enumTypes.qr, enumIcons.group)) : [],
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -49,49 +137,40 @@ export const commonEnumProviders = {
|
|||||||
* @param {('all' | 'existing' | 'not-existing')?} [mode='all'] - Which types of tags to show
|
* @param {('all' | 'existing' | 'not-existing')?} [mode='all'] - Which types of tags to show
|
||||||
* @returns {() => SlashCommandEnumValue[]}
|
* @returns {() => SlashCommandEnumValue[]}
|
||||||
*/
|
*/
|
||||||
tagsForChar: (mode) => (/** @type {SlashCommandExecutor} */ executor) => {
|
tagsForChar: (mode = 'all') => (/** @type {SlashCommandExecutor} */ executor) => {
|
||||||
mode = mode ?? 'all';
|
|
||||||
// Try to see if we can find the char during execution to filter down the tags list some more. Otherwise take all tags.
|
// Try to see if we can find the char during execution to filter down the tags list some more. Otherwise take all tags.
|
||||||
const key = searchCharByName(substituteParams(/**@type {string?}*/(executor.namedArgumentList.find(it => it.name == 'name')?.value)), { suppressLogging: true });
|
const charName = executor.namedArgumentList.find(it => it.name == 'name')?.value;
|
||||||
|
if (charName instanceof SlashCommandClosure) throw new Error('Argument \'name\' does not support closures');
|
||||||
|
const key = searchCharByName(substituteParams(charName), { suppressLogging: true });
|
||||||
const assigned = key ? getTagsList(key) : [];
|
const assigned = key ? getTagsList(key) : [];
|
||||||
return tags.filter(it => !key || mode === 'all' || mode === 'existing' && assigned.includes(it) || mode === 'not-existing' && !assigned.includes(it))
|
return tags.filter(it => !key || mode === 'all' || mode === 'existing' && assigned.includes(it) || mode === 'not-existing' && !assigned.includes(it))
|
||||||
.map(it => new SlashCommandEnumValue(it.name, it.title));
|
.map(it => new SlashCommandEnumValue(it.name, null, enumTypes.command, enumIcons.tag));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All messages in the current chat, returning the message id
|
||||||
|
* @returns {SlashCommandEnumValue[]}
|
||||||
|
*/
|
||||||
|
messages: () => chat.map((mes, i) => new SlashCommandEnumValue(String(i), `${mes.name}: ${mes.mes}`, enumTypes.number, mes.is_user ? enumIcons.user : mes.is_system ? enumIcons.system : enumIcons.assistant)),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All existing worlds / lorebooks
|
* All existing worlds / lorebooks
|
||||||
*
|
*
|
||||||
* @returns {SlashCommandEnumValue[]}
|
* @returns {SlashCommandEnumValue[]}
|
||||||
*/
|
*/
|
||||||
worlds: () => $('#world_info').children().toArray().map(x => new SlashCommandEnumValue(x.textContent)),
|
worlds: () => $('#world_info').children().toArray().map(x => new SlashCommandEnumValue(x.textContent, null, enumTypes.name, enumIcons.world)),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the enum values for boolean type, with class and icon
|
|
||||||
*
|
|
||||||
* @return {Array<SlashCommandEnumValue>} An array of SlashCommandEnumValue objects representing the boolean values 'true' and 'false'.
|
|
||||||
*/
|
|
||||||
export function getEnumBooleanValues() {
|
|
||||||
return [new SlashCommandEnumValue('true', null, 'boolean', getEnumIconByValueType('boolean')), new SlashCommandEnumValue('false', null, 'boolean', getEnumIconByValueType('boolean'))];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the unicode icon for the given enum value type
|
* Get the unicode icon for the given enum value type
|
||||||
|
*
|
||||||
|
* Can also confert nullable data types to their non-nullable counterparts
|
||||||
|
*
|
||||||
* @param {string} type The type of the enum value
|
* @param {string} type The type of the enum value
|
||||||
* @returns {string} the unicode icon
|
* @returns {string} the unicode icon
|
||||||
*/
|
*/
|
||||||
export function getEnumIconByValueType(type) {
|
export function getEnumIcon(type) {
|
||||||
// Remove nullable types definition to match type icon
|
// Remove possible nullable types definition to match type icon
|
||||||
type = type.replace(/\?$/, '');
|
type = type.replace(/\?$/, '');
|
||||||
|
return enumIcons[type] ?? enumIcons.default;
|
||||||
switch (type) {
|
|
||||||
case 'boolean': return '🔲';
|
|
||||||
case 'string': return '📝';
|
|
||||||
case 'number': return '1️⃣';
|
|
||||||
case 'array': return '📦';
|
|
||||||
case 'enum': return '📚';
|
|
||||||
case 'dictionary': return '📖';
|
|
||||||
case 'closure': return '🧩';
|
|
||||||
default: return '◊';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,63 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {'enum' | 'command' | 'namedArgument' | 'variable' | 'qr' | 'macro' | 'number' | 'name'} EnumType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of the enum types that can be used with `SlashCommandEnumValue`
|
||||||
|
*
|
||||||
|
* Contains documentation on which color this will result to
|
||||||
|
*/
|
||||||
|
export const enumTypes = {
|
||||||
|
/** 'enum' - [string] - light orange @type {EnumType} */
|
||||||
|
enum: 'enum',
|
||||||
|
/** 'command' - [cmd] - light yellow @type {EnumType} */
|
||||||
|
command: 'command',
|
||||||
|
/** 'namedArgument' - [argName] - sky blue @type {EnumType} */
|
||||||
|
namedArgument: 'namedArgument',
|
||||||
|
/** 'variable' - [punctuationL1] - pink @type {EnumType} */
|
||||||
|
variable: 'variable',
|
||||||
|
/** 'qr' - [variable] - light blue @type {EnumType} */
|
||||||
|
qr: 'qr',
|
||||||
|
/** 'macro' - [variableLanguage] - blue @type {EnumType} */
|
||||||
|
macro: 'macro',
|
||||||
|
/** 'number' - [number] - light green @type {EnumType} */
|
||||||
|
number: 'number',
|
||||||
|
/** 'name' - [type] - forest green @type {EnumType} */
|
||||||
|
name: 'name',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the enum type based on the provided index
|
||||||
|
*
|
||||||
|
* Can be used to get differing colors or even random colors, by providing the index of a unique set
|
||||||
|
*
|
||||||
|
* @param {number?} index - The index used to retrieve the enum type
|
||||||
|
* @return {EnumType} The enum type corresponding to the index
|
||||||
|
*/
|
||||||
|
getBasedOnIndex(index) {
|
||||||
|
const keys = Object.keys(this);
|
||||||
|
return this[keys[(index ?? 0) % keys.length]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class SlashCommandEnumValue {
|
export class SlashCommandEnumValue {
|
||||||
/**@type {string}*/ value;
|
/**@type {string}*/ value;
|
||||||
/**@type {string}*/ description;
|
/**@type {string}*/ description;
|
||||||
/**@type {string}*/ type = 'enum';
|
/**@type {EnumType}*/ type = 'enum';
|
||||||
/**@type {string}*/ typeIcon = '◊';
|
/**@type {string}*/ typeIcon = '◊';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constructor for creating a SlashCommandEnumValue instance.
|
||||||
|
*
|
||||||
|
* @param {string} value - The value
|
||||||
|
* @param {string?} description - Optional description, displayed in a second line
|
||||||
|
* @param {EnumType?} type - type of the enum (defining its color)
|
||||||
|
* @param {string} typeIcon - The icon to display (Can be pulled from `enumIcons` for common ones)
|
||||||
|
*/
|
||||||
constructor(value, description = null, type = 'enum', typeIcon = '◊') {
|
constructor(value, description = null, type = 'enum', typeIcon = '◊') {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.type = type;
|
this.type = type ?? 'enum';
|
||||||
this.typeIcon = typeIcon;
|
this.typeIcon = typeIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import { SlashCommandAutoCompleteNameResult } from './SlashCommandAutoCompleteNa
|
|||||||
import { SlashCommandUnnamedArgumentAssignment } from './SlashCommandUnnamedArgumentAssignment.js';
|
import { SlashCommandUnnamedArgumentAssignment } from './SlashCommandUnnamedArgumentAssignment.js';
|
||||||
import { SlashCommandEnumValue } from './SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue } from './SlashCommandEnumValue.js';
|
||||||
import { MacroAutoCompleteOption } from '../autocomplete/MacroAutoCompleteOption.js';
|
import { MacroAutoCompleteOption } from '../autocomplete/MacroAutoCompleteOption.js';
|
||||||
|
import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js';
|
||||||
|
|
||||||
/** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */
|
/** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */
|
||||||
/** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */
|
/** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */
|
||||||
@ -134,7 +135,7 @@ export class SlashCommandParser {
|
|||||||
description: 'The state of the parser flag to set.',
|
description: 'The state of the parser flag to set.',
|
||||||
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
||||||
defaultValue: 'on',
|
defaultValue: 'on',
|
||||||
enumList: ['on', 'off'],
|
enumList: commonEnumProviders.boolean('onOff')(),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
splitUnnamedArgument: true,
|
splitUnnamedArgument: true,
|
||||||
|
@ -328,6 +328,7 @@ function listVariablesCallback() {
|
|||||||
* @param {(string|SlashCommandClosure)[]} value
|
* @param {(string|SlashCommandClosure)[]} value
|
||||||
*/
|
*/
|
||||||
async function whileCallback(args, value) {
|
async function whileCallback(args, value) {
|
||||||
|
if (args.guard instanceof SlashCommandClosure) throw new Error('argument \'guard\' cannot be a closure for command /while');
|
||||||
const isGuardOff = isFalseBoolean(args.guard);
|
const isGuardOff = isFalseBoolean(args.guard);
|
||||||
const iterations = isGuardOff ? Number.MAX_SAFE_INTEGER : MAX_LOOPS;
|
const iterations = isGuardOff ? Number.MAX_SAFE_INTEGER : MAX_LOOPS;
|
||||||
/**@type {string|SlashCommandClosure} */
|
/**@type {string|SlashCommandClosure} */
|
||||||
@ -1199,12 +1200,22 @@ export function registerVariableCommands() {
|
|||||||
callback: ifCallback,
|
callback: ifCallback,
|
||||||
returns: 'result of the executed command ("then" or "else")',
|
returns: 'result of the executed command ("then" or "else")',
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument(
|
SlashCommandNamedArgument.fromProps({
|
||||||
'left', 'left operand', [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER], true,
|
name: 'left',
|
||||||
),
|
description: 'left operand',
|
||||||
new SlashCommandNamedArgument(
|
typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER],
|
||||||
'right', 'right operand', [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER], true,
|
isRequired: true,
|
||||||
),
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'right',
|
||||||
|
description: 'right operand',
|
||||||
|
typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
|
}),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
|
'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
|
||||||
new SlashCommandEnumValue('gt', 'a > b'),
|
new SlashCommandEnumValue('gt', 'a > b'),
|
||||||
@ -1214,8 +1225,8 @@ export function registerVariableCommands() {
|
|||||||
new SlashCommandEnumValue('eq', 'a == b'),
|
new SlashCommandEnumValue('eq', 'a == b'),
|
||||||
new SlashCommandEnumValue('neq', 'a !== b'),
|
new SlashCommandEnumValue('neq', 'a !== b'),
|
||||||
new SlashCommandEnumValue('not', '!a'),
|
new SlashCommandEnumValue('not', '!a'),
|
||||||
new SlashCommandEnumValue('in', 'a includes b'),
|
new SlashCommandEnumValue('in', 'a includes b'),
|
||||||
new SlashCommandEnumValue('nin', 'a not includes b'),
|
new SlashCommandEnumValue('nin', 'a not includes b'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
@ -1267,12 +1278,22 @@ export function registerVariableCommands() {
|
|||||||
callback: whileCallback,
|
callback: whileCallback,
|
||||||
returns: 'result of the last executed command',
|
returns: 'result of the last executed command',
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument(
|
SlashCommandNamedArgument.fromProps({
|
||||||
'left', 'left operand', [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER], true,
|
name: 'left',
|
||||||
),
|
description: 'left operand',
|
||||||
new SlashCommandNamedArgument(
|
typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER],
|
||||||
'right', 'right operand', [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER], true,
|
isRequired: true,
|
||||||
),
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'right',
|
||||||
|
description: 'right operand',
|
||||||
|
typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
forceEnum: false,
|
||||||
|
}),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
|
'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
|
||||||
new SlashCommandEnumValue('gt', 'a > b'),
|
new SlashCommandEnumValue('gt', 'a > b'),
|
||||||
@ -1282,12 +1303,12 @@ export function registerVariableCommands() {
|
|||||||
new SlashCommandEnumValue('eq', 'a == b'),
|
new SlashCommandEnumValue('eq', 'a == b'),
|
||||||
new SlashCommandEnumValue('neq', 'a !== b'),
|
new SlashCommandEnumValue('neq', 'a !== b'),
|
||||||
new SlashCommandEnumValue('not', '!a'),
|
new SlashCommandEnumValue('not', '!a'),
|
||||||
new SlashCommandEnumValue('in', 'a includes b'),
|
new SlashCommandEnumValue('in', 'a includes b'),
|
||||||
new SlashCommandEnumValue('nin', 'a not includes b'),
|
new SlashCommandEnumValue('nin', 'a not includes b'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'guard', 'disable loop iteration limit', [ARGUMENT_TYPE.STRING], false, false, null, ['off'],
|
'guard', 'disable loop iteration limit', [ARGUMENT_TYPE.STRING], false, false, null, commonEnumProviders.boolean('onOff')(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
|
@ -13,8 +13,10 @@ import { getRegexedString, regex_placement } from './extensions/regex/engine.js'
|
|||||||
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
||||||
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js';
|
||||||
import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
import { commonEnumProviders, getEnumIconByValueType } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders, enumIcons, getEnumIcon } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
|
import { SlashCommandExecutor } from './slash-commands/SlashCommandExecutor.js';
|
||||||
|
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
world_info,
|
world_info,
|
||||||
@ -703,14 +705,41 @@ function registerWorldInfoSlashCommands() {
|
|||||||
/** A collection of local enum providers for this context of world info */
|
/** A collection of local enum providers for this context of world info */
|
||||||
const localEnumProviders = {
|
const localEnumProviders = {
|
||||||
/** All possible fields that can be set in a WI entry */
|
/** All possible fields that can be set in a WI entry */
|
||||||
wiEntryFields: () => Object.entries(newEntryDefinition).map(([key, value]) => new SlashCommandEnumValue(key, `[${value.type}] default: ${(typeof value.default === 'string' ? `'${value.default}'` : value.default)}`, 'property', getEnumIconByValueType(value.type))),
|
wiEntryFields: () => Object.entries(newEntryDefinition).map(([key, value]) =>
|
||||||
|
new SlashCommandEnumValue(key, `[${value.type}] default: ${(typeof value.default === 'string' ? `'${value.default}'` : value.default)}`,
|
||||||
|
enumTypes.enum, getEnumIcon(value.type))),
|
||||||
|
|
||||||
|
/** All existing UIDs based on the file argument as world name */
|
||||||
|
wiUids: (/** @type {SlashCommandExecutor} */ executor) => {
|
||||||
|
const file = executor.namedArgumentList.find(it => it.name == 'file')?.value;
|
||||||
|
if (file instanceof SlashCommandClosure) throw new Error('Argument \'file\' does not support closures');
|
||||||
|
// Try find world from cache
|
||||||
|
const world = worldInfoCache[file];
|
||||||
|
if (!world) return [];
|
||||||
|
return Object.entries(world.entries).map(([uid, data]) =>
|
||||||
|
new SlashCommandEnumValue(uid, `${data.comment ? `${data.comment}: ` : ''}${data.key.join(', ')}${data.keysecondary?.length ? ` [${Object.entries(world_info_logic).find(([_, value]) => value == data.selectiveLogic)[0]}] ${data.keysecondary.join(', ')}` : ''} [${getWiPositionString(data)}]`,
|
||||||
|
enumTypes.enum, enumIcons.getWiStatusIcon(data)));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getWiPositionString(entry) {
|
||||||
|
switch (entry.position) {
|
||||||
|
case world_info_position.before: return '↑Char';
|
||||||
|
case world_info_position.after: return '↓Char';
|
||||||
|
case world_info_position.EMTop: return '↑EM';
|
||||||
|
case world_info_position.EMBottom: return '↓EM';
|
||||||
|
case world_info_position.ANTop: return '↑AT';
|
||||||
|
case world_info_position.ANBottom: return '↓AT';
|
||||||
|
case world_info_position.atDepth: return `@D${enumIcons.getRoleIcon(entry.role)}`;
|
||||||
|
default: return '<Unknown>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'world',
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'world',
|
||||||
callback: onWorldInfoChange,
|
callback: onWorldInfoChange,
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'state', 'set world state', [ARGUMENT_TYPE.STRING], false, false, null, ['off', 'toggle'],
|
'state', 'set world state', [ARGUMENT_TYPE.STRING], false, false, null, commonEnumProviders.boolean('onOffToggle')(),
|
||||||
),
|
),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'silent', 'suppress toast messages', [ARGUMENT_TYPE.BOOLEAN], false,
|
'silent', 'suppress toast messages', [ARGUMENT_TYPE.BOOLEAN], false,
|
||||||
@ -747,7 +776,7 @@ function registerWorldInfoSlashCommands() {
|
|||||||
description: 'book name',
|
description: 'book name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: commonEnumProviders.loreBooks,
|
enumProvider: commonEnumProviders.worlds,
|
||||||
}),
|
}),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'field',
|
name: 'field',
|
||||||
@ -786,7 +815,7 @@ function registerWorldInfoSlashCommands() {
|
|||||||
description: 'book name',
|
description: 'book name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: commonEnumProviders.loreBooks,
|
enumProvider: commonEnumProviders.worlds,
|
||||||
}),
|
}),
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'field',
|
name: 'field',
|
||||||
@ -797,9 +826,12 @@ function registerWorldInfoSlashCommands() {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
SlashCommandArgument.fromProps({
|
||||||
'UID', ARGUMENT_TYPE.STRING, true,
|
description: 'record UID',
|
||||||
),
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: localEnumProviders.wiUids,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
helpString: `
|
helpString: `
|
||||||
<div>
|
<div>
|
||||||
@ -825,7 +857,7 @@ function registerWorldInfoSlashCommands() {
|
|||||||
description: 'book name',
|
description: 'book name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: commonEnumProviders.loreBooks,
|
enumProvider: commonEnumProviders.worlds,
|
||||||
}),
|
}),
|
||||||
new SlashCommandNamedArgument(
|
new SlashCommandNamedArgument(
|
||||||
'key', 'record key', [ARGUMENT_TYPE.STRING], false,
|
'key', 'record key', [ARGUMENT_TYPE.STRING], false,
|
||||||
@ -859,11 +891,15 @@ function registerWorldInfoSlashCommands() {
|
|||||||
description: 'book name',
|
description: 'book name',
|
||||||
typeList: [ARGUMENT_TYPE.STRING],
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
enumProvider: commonEnumProviders.loreBooks,
|
enumProvider: commonEnumProviders.worlds,
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'uid',
|
||||||
|
description: 'record UID',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: localEnumProviders.wiUids,
|
||||||
}),
|
}),
|
||||||
new SlashCommandNamedArgument(
|
|
||||||
'uid', 'record UID', [ARGUMENT_TYPE.STRING], true,
|
|
||||||
),
|
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'field',
|
name: 'field',
|
||||||
description: 'field name (default: content)',
|
description: 'field name (default: content)',
|
||||||
@ -910,9 +946,9 @@ async function loadWorldInfoData(name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worldInfoCache[name]) {
|
// if (worldInfoCache[name]) {
|
||||||
return worldInfoCache[name];
|
// return worldInfoCache[name];
|
||||||
}
|
// }
|
||||||
|
|
||||||
const response = await fetch('/api/worldinfo/get', {
|
const response = await fetch('/api/worldinfo/get', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -2558,7 +2594,7 @@ async function saveWorldInfo(name, data, immediately) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete worldInfoCache[name];
|
// delete worldInfoCache[name];
|
||||||
|
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
return await _save(name, data);
|
return await _save(name, data);
|
||||||
@ -3555,6 +3591,7 @@ function onWorldInfoChange(args, text) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'on':
|
||||||
default: {
|
default: {
|
||||||
selected_world_info.push(name);
|
selected_world_info.push(name);
|
||||||
wiElement.prop('selected', true);
|
wiElement.prop('selected', true);
|
||||||
|
@ -1487,6 +1487,14 @@ body[data-stscript-style] .autoComplete [data-option-type] {
|
|||||||
&[data-option-type="macro"] .type {
|
&[data-option-type="macro"] .type {
|
||||||
color: var(--ac-color-variableLanguage);
|
color: var(--ac-color-variableLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[data-option-type="number"] .type {
|
||||||
|
color: var(--ac-color-number);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-option-type="name"] .type {
|
||||||
|
color: var(--ac-color-type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-stscript-style] .hljs.language-stscript {
|
body[data-stscript-style] .hljs.language-stscript {
|
||||||
|
Reference in New Issue
Block a user