Merge branch 'staging' into translation-improvements
| @@ -15,6 +15,11 @@ | |||
| 15 | "**/node_modules/*", | 15 | "**/node_modules/*", |
| 16 | "public/lib", | 16 | "public/lib", |
| 17 | "backups/*", | 17 | "backups/*", |
| 18 | "data/*" | 18 | "data/*", |
| 19 | "**/dist/*", | ||
| 20 | "dist/*", | ||
| 21 | "cache/*", | ||
| 22 | "src/tokenizers/*", | ||
| 23 | "docker/*", | ||
| 19 | ] | 24 | ] |
| 20 | } | 25 | } |
| @@ -159,7 +159,7 @@ import { | |||
| 159 | import { debounce_timeout } from './scripts/constants.js'; | 159 | import { debounce_timeout } from './scripts/constants.js'; |
| 160 | 160 | ||
| 161 | import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, loadExtensionSettings, renderExtensionTemplate, renderExtensionTemplateAsync, runGenerationInterceptors, saveMetadataDebounced, writeExtensionField } from './scripts/extensions.js'; | 161 | import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, loadExtensionSettings, renderExtensionTemplate, renderExtensionTemplateAsync, runGenerationInterceptors, saveMetadataDebounced, writeExtensionField } from './scripts/extensions.js'; |
| 162 | import { COMMENT_NAME_DEFAULT, executeSlashCommands, executeSlashCommandsOnChatInput, getSlashCommandsHelp, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, registerSlashCommand, stopScriptExecution } from './scripts/slash-commands.js'; | 162 | import { COMMENT_NAME_DEFAULT, executeSlashCommands, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, registerSlashCommand, stopScriptExecution } from './scripts/slash-commands.js'; |
| 163 | import { | 163 | import { |
| 164 | tag_map, | 164 | tag_map, |
| 165 | tags, | 165 | tags, |
| @@ -911,6 +911,7 @@ async function firstLoadInit() { | |||
| 911 | initKeyboard(); | 911 | initKeyboard(); |
| 912 | initDynamicStyles(); | 912 | initDynamicStyles(); |
| 913 | initTags(); | 913 | initTags(); |
| 914 | initDefaultSlashCommands(); | ||
| 914 | await getUserAvatars(true, user_avatar); | 915 | await getUserAvatars(true, user_avatar); |
| 915 | await getCharacters(); | 916 | await getCharacters(); |
| 916 | await getBackgrounds(); | 917 | await getBackgrounds(); |
| @@ -356,6 +356,7 @@ jQuery(async function () { | |||
| 356 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'llamacpp' && textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) || | 356 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'llamacpp' && textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) || |
| 357 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ooba' && textgenerationwebui_settings.server_urls[textgen_types.OOBA]) || | 357 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ooba' && textgenerationwebui_settings.server_urls[textgen_types.OOBA]) || |
| 358 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'koboldcpp' && textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) || | 358 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'koboldcpp' && textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) || |
| 359 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'vllm' && textgenerationwebui_settings.server_urls[textgen_types.VLLM]) || | ||
| 359 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'custom') || | 360 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'custom') || |
| 360 | extension_settings.caption.source === 'local' || | 361 | extension_settings.caption.source === 'local' || |
| 361 | extension_settings.caption.source === 'horde'; | 362 | extension_settings.caption.source === 'horde'; |
| @@ -26,6 +26,7 @@ | |||
| 26 | <option value="openai">OpenAI</option> | 26 | <option value="openai">OpenAI</option> |
| 27 | <option value="openrouter">OpenRouter</option> | 27 | <option value="openrouter">OpenRouter</option> |
| 28 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> | 28 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> |
| 29 | <option value="vllm">vLLM</option> | ||
| 29 | </select> | 30 | </select> |
| 30 | </div> | 31 | </div> |
| 31 | <div class="flex1 flex-container flexFlowColumn flexNoGap"> | 32 | <div class="flex1 flex-container flexFlowColumn flexNoGap"> |
| @@ -66,6 +67,7 @@ | |||
| 66 | <option data-type="llamacpp" value="llamacpp_current" data-i18n="currently_loaded">[Currently loaded]</option> | 67 | <option data-type="llamacpp" value="llamacpp_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 67 | <option data-type="ooba" value="ooba_current" data-i18n="currently_loaded">[Currently loaded]</option> | 68 | <option data-type="ooba" value="ooba_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 68 | <option data-type="koboldcpp" value="koboldcpp_current" data-i18n="currently_loaded">[Currently loaded]</option> | 69 | <option data-type="koboldcpp" value="koboldcpp_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 70 | <option data-type="vllm" value="vllm_current" data-i18n="currently_selected">[Currently selected]</option> | ||
| 69 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> | 71 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> |
| 70 | </select> | 72 | </select> |
| 71 | </div> | 73 | </div> |
| @@ -34,6 +34,7 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 34 | const isCustom = extension_settings.caption.multimodal_api === 'custom'; | 34 | const isCustom = extension_settings.caption.multimodal_api === 'custom'; |
| 35 | const isOoba = extension_settings.caption.multimodal_api === 'ooba'; | 35 | const isOoba = extension_settings.caption.multimodal_api === 'ooba'; |
| 36 | const isKoboldCpp = extension_settings.caption.multimodal_api === 'koboldcpp'; | 36 | const isKoboldCpp = extension_settings.caption.multimodal_api === 'koboldcpp'; |
| 37 | const isVllm = extension_settings.caption.multimodal_api === 'vllm'; | ||
| 37 | const base64Bytes = base64Img.length * 0.75; | 38 | const base64Bytes = base64Img.length * 0.75; |
| 38 | const compressionLimit = 2 * 1024 * 1024; | 39 | const compressionLimit = 2 * 1024 * 1024; |
| 39 | if ((['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { | 40 | if ((['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { |
| @@ -65,6 +66,14 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 65 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; | 66 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 69 | if (isVllm) { | ||
| 70 | if (extension_settings.caption.multimodal_model === 'vllm_current') { | ||
| 71 | requestBody.model = textgenerationwebui_settings.vllm_model; | ||
| 72 | } | ||
| 73 | |||
| 74 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.VLLM]; | ||
| 75 | } | ||
| 76 | |||
| 68 | if (isLlamaCpp) { | 77 | if (isLlamaCpp) { |
| 69 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; | 78 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; |
| 70 | } | 79 | } |
| @@ -151,6 +160,14 @@ function throwIfInvalidModel(useReverseProxy) { | |||
| 151 | throw new Error('KoboldCpp server URL is not set.'); | 160 | throw new Error('KoboldCpp server URL is not set.'); |
| 152 | } | 161 | } |
| 153 | 162 | ||
| 163 | if (extension_settings.caption.multimodal_api === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM]) { | ||
| 164 | throw new Error('vLLM server URL is not set.'); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (extension_settings.caption.multimodal_api === 'vllm' && extension_settings.caption.multimodal_model === 'vllm_current' && !textgenerationwebui_settings.vllm_model) { | ||
| 168 | throw new Error('vLLM model is not set.'); | ||
| 169 | } | ||
| 170 | |||
| 154 | if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) { | 171 | if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) { |
| 155 | throw new Error('Custom API URL is not set.'); | 172 | throw new Error('Custom API URL is not set.'); |
| 156 | } | 173 | } |
| @@ -10,6 +10,7 @@ import { NovelTtsProvider } from './novel.js'; | |||
| 10 | import { power_user } from '../../power-user.js'; | 10 | import { power_user } from '../../power-user.js'; |
| 11 | import { OpenAITtsProvider } from './openai.js'; | 11 | import { OpenAITtsProvider } from './openai.js'; |
| 12 | import { XTTSTtsProvider } from './xtts.js'; | 12 | import { XTTSTtsProvider } from './xtts.js'; |
| 13 | import { VITSTtsProvider } from './vits.js'; | ||
| 13 | import { GSVITtsProvider } from './gsvi.js'; | 14 | import { GSVITtsProvider } from './gsvi.js'; |
| 14 | import { SBVits2TtsProvider } from './sbvits2.js'; | 15 | import { SBVits2TtsProvider } from './sbvits2.js'; |
| 15 | import { AllTalkTtsProvider } from './alltalk.js'; | 16 | import { AllTalkTtsProvider } from './alltalk.js'; |
| @@ -83,6 +84,7 @@ const ttsProviders = { | |||
| 83 | ElevenLabs: ElevenLabsTtsProvider, | 84 | ElevenLabs: ElevenLabsTtsProvider, |
| 84 | Silero: SileroTtsProvider, | 85 | Silero: SileroTtsProvider, |
| 85 | XTTSv2: XTTSTtsProvider, | 86 | XTTSv2: XTTSTtsProvider, |
| 87 | VITS: VITSTtsProvider, | ||
| 86 | GSVI: GSVITtsProvider, | 88 | GSVI: GSVITtsProvider, |
| 87 | SBVits2: SBVits2TtsProvider, | 89 | SBVits2: SBVits2TtsProvider, |
| 88 | System: SystemTtsProvider, | 90 | System: SystemTtsProvider, |
| @@ -0,0 +1,404 @@ | |||
| 1 | import { getPreviewString, saveTtsProviderSettings } from './index.js'; | ||
| 2 | |||
| 3 | export { VITSTtsProvider }; | ||
| 4 | |||
| 5 | class VITSTtsProvider { | ||
| 6 | //########// | ||
| 7 | // Config // | ||
| 8 | //########// | ||
| 9 | |||
| 10 | settings; | ||
| 11 | ready = false; | ||
| 12 | voices = []; | ||
| 13 | separator = '. '; | ||
| 14 | audioElement = document.createElement('audio'); | ||
| 15 | |||
| 16 | /** | ||
| 17 | * Perform any text processing before passing to TTS engine. | ||
| 18 | * @param {string} text Input text | ||
| 19 | * @returns {string} Processed text | ||
| 20 | */ | ||
| 21 | processText(text) { | ||
| 22 | return text; | ||
| 23 | } | ||
| 24 | |||
| 25 | audioFormats = ['wav', 'ogg', 'silk', 'mp3', 'flac']; | ||
| 26 | |||
| 27 | languageLabels = { | ||
| 28 | 'Auto': 'auto', | ||
| 29 | 'Chinese': 'zh', | ||
| 30 | 'English': 'en', | ||
| 31 | 'Japanese': 'ja', | ||
| 32 | 'Korean': 'ko', | ||
| 33 | }; | ||
| 34 | |||
| 35 | langKey2LangCode = { | ||
| 36 | 'zh': 'zh-CN', | ||
| 37 | 'en': 'en-US', | ||
| 38 | 'ja': 'ja-JP', | ||
| 39 | 'ko': 'ko-KR', | ||
| 40 | }; | ||
| 41 | |||
| 42 | modelTypes = { | ||
| 43 | VITS: 'VITS', | ||
| 44 | W2V2_VITS: 'W2V2-VITS', | ||
| 45 | BERT_VITS2: 'BERT-VITS2', | ||
| 46 | }; | ||
| 47 | |||
| 48 | defaultSettings = { | ||
| 49 | provider_endpoint: 'http://localhost:23456', | ||
| 50 | format: 'wav', | ||
| 51 | lang: 'auto', | ||
| 52 | length: 1.0, | ||
| 53 | noise: 0.33, | ||
| 54 | noisew: 0.4, | ||
| 55 | segment_size: 50, | ||
| 56 | streaming: false, | ||
| 57 | dim_emotion: 0, | ||
| 58 | sdp_ratio: 0.2, | ||
| 59 | emotion: 0, | ||
| 60 | text_prompt: '', | ||
| 61 | style_text: '', | ||
| 62 | style_weight: 1, | ||
| 63 | }; | ||
| 64 | |||
| 65 | get settingsHtml() { | ||
| 66 | let html = ` | ||
| 67 | <label for="vits_lang">Text Language</label> | ||
| 68 | <select id="vits_lang">`; | ||
| 69 | |||
| 70 | for (let language in this.languageLabels) { | ||
| 71 | if (this.languageLabels[language] == this.settings?.lang) { | ||
| 72 | html += `<option value="${this.languageLabels[language]}" selected="selected">${language}</option>`; | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | html += `<option value="${this.languageLabels[language]}">${language}</option>`; | ||
| 76 | } | ||
| 77 | |||
| 78 | html += ` | ||
| 79 | </select> | ||
| 80 | <label>VITS / W2V2-VITS / Bert-VITS2 Settings:</label><br/> | ||
| 81 | <label for="vits_endpoint">Provider Endpoint:</label> | ||
| 82 | <input id="vits_endpoint" type="text" class="text_pole" maxlength="250" value="${this.defaultSettings.provider_endpoint}"/> | ||
| 83 | <span>Use <a target="_blank" href="https://github.com/Artrajz/vits-simple-api">vits-simple-api</a>.</span><br/> | ||
| 84 | |||
| 85 | <label for="vits_format">Audio format:</label> | ||
| 86 | <select id="vits_format">`; | ||
| 87 | |||
| 88 | for (let format of this.audioFormats) { | ||
| 89 | if (format == this.settings?.format) { | ||
| 90 | html += `<option value="${format}" selected="selected">${format}</option>`; | ||
| 91 | continue; | ||
| 92 | } | ||
| 93 | html += `<option value="${format}">${format}</option>`; | ||
| 94 | } | ||
| 95 | |||
| 96 | html += ` | ||
| 97 | </select> | ||
| 98 | <label for="vits_length">Audio length: <span id="vits_length_output">${this.defaultSettings.length}</span></label> | ||
| 99 | <input id="vits_length" type="range" value="${this.defaultSettings.length}" min="0.0" max="5" step="0.01" /> | ||
| 100 | |||
| 101 | <label for="vits_noise">Noise: <span id="vits_noise_output">${this.defaultSettings.noise}</span></label> | ||
| 102 | <input id="vits_noise" type="range" value="${this.defaultSettings.noise}" min="0.1" max="2" step="0.01" /> | ||
| 103 | |||
| 104 | <label for="vits_noisew">SDP noise: <span id="vits_noisew_output">${this.defaultSettings.noisew}</span></label> | ||
| 105 | <input id="vits_noisew" type="range" value="${this.defaultSettings.noisew}" min="0.1" max="2" step="0.01" /> | ||
| 106 | |||
| 107 | <label for="vits_segment_size">Segment Size: <span id="vits_segment_size_output">${this.defaultSettings.segment_size}</span></label> | ||
| 108 | <input id="vits_segment_size" type="range" value="${this.defaultSettings.segment_size}" min="0" max="1000" step="1" /> | ||
| 109 | |||
| 110 | <label for="vits_streaming" class="checkbox_label"> | ||
| 111 | <input id="vits_streaming" type="checkbox" /> | ||
| 112 | <span>Streaming</span> | ||
| 113 | </label> | ||
| 114 | |||
| 115 | <label>W2V2-VITS Settings:</label><br/> | ||
| 116 | <label for="vits_dim_emotion">Dimensional emotion:</label> | ||
| 117 | <input id="vits_dim_emotion" type="number" class="text_pole" min="0" max="5457" step="1" value="${this.defaultSettings.dim_emotion}"/> | ||
| 118 | |||
| 119 | <label>BERT-VITS2 Settings:</label><br/> | ||
| 120 | <label for="vits_sdp_ratio">sdp_ratio: <span id="vits_sdp_ratio_output">${this.defaultSettings.sdp_ratio}</span></label> | ||
| 121 | <input id="vits_sdp_ratio" type="range" value="${this.defaultSettings.sdp_ratio}" min="0.0" max="1" step="0.01" /> | ||
| 122 | |||
| 123 | <label for="vits_emotion">emotion: <span id="vits_emotion_output">${this.defaultSettings.emotion}</span></label> | ||
| 124 | <input id="vits_emotion" type="range" value="${this.defaultSettings.emotion}" min="0" max="9" step="1" /> | ||
| 125 | |||
| 126 | <label for="vits_text_prompt">Text Prompt:</label> | ||
| 127 | <input id="vits_text_prompt" type="text" class="text_pole" maxlength="512" value="${this.defaultSettings.text_prompt}"/> | ||
| 128 | |||
| 129 | <label for="vits_style_text">Style text:</label> | ||
| 130 | <input id="vits_style_text" type="text" class="text_pole" maxlength="512" value="${this.defaultSettings.style_text}"/> | ||
| 131 | |||
| 132 | <label for="vits_style_weight">Style weight <span id="vits_style_weight_output">${this.defaultSettings.style_weight}</span></label> | ||
| 133 | <input id="vits_style_weight" type="range" value="${this.defaultSettings.style_weight}" min="0" max="1" step="0.01" /> | ||
| 134 | `; | ||
| 135 | |||
| 136 | return html; | ||
| 137 | } | ||
| 138 | |||
| 139 | onSettingsChange() { | ||
| 140 | // Used when provider settings are updated from UI | ||
| 141 | this.settings.provider_endpoint = $('#vits_endpoint').val(); | ||
| 142 | this.settings.lang = $('#vits_lang').val(); | ||
| 143 | this.settings.format = $('#vits_format').val(); | ||
| 144 | this.settings.dim_emotion = $('#vits_dim_emotion').val(); | ||
| 145 | this.settings.text_prompt = $('#vits_text_prompt').val(); | ||
| 146 | this.settings.style_text = $('#vits_style_text').val(); | ||
| 147 | |||
| 148 | // Update the default TTS settings based on input fields | ||
| 149 | this.settings.length = $('#vits_length').val(); | ||
| 150 | this.settings.noise = $('#vits_noise').val(); | ||
| 151 | this.settings.noisew = $('#vits_noisew').val(); | ||
| 152 | this.settings.segment_size = $('#vits_segment_size').val(); | ||
| 153 | this.settings.streaming = $('#vits_streaming').is(':checked'); | ||
| 154 | this.settings.sdp_ratio = $('#vits_sdp_ratio').val(); | ||
| 155 | this.settings.emotion = $('#vits_emotion').val(); | ||
| 156 | this.settings.style_weight = $('#vits_style_weight').val(); | ||
| 157 | |||
| 158 | // Update the UI to reflect changes | ||
| 159 | $('#vits_length_output').text(this.settings.length); | ||
| 160 | $('#vits_noise_output').text(this.settings.noise); | ||
| 161 | $('#vits_noisew_output').text(this.settings.noisew); | ||
| 162 | $('#vits_segment_size_output').text(this.settings.segment_size); | ||
| 163 | $('#vits_sdp_ratio_output').text(this.settings.sdp_ratio); | ||
| 164 | $('#vits_emotion_output').text(this.settings.emotion); | ||
| 165 | $('#vits_style_weight_output').text(this.settings.style_weight); | ||
| 166 | |||
| 167 | saveTtsProviderSettings(); | ||
| 168 | this.changeTTSSettings(); | ||
| 169 | } | ||
| 170 | |||
| 171 | async loadSettings(settings) { | ||
| 172 | // Pupulate Provider UI given input settings | ||
| 173 | if (Object.keys(settings).length == 0) { | ||
| 174 | console.info('Using default TTS Provider settings'); | ||
| 175 | } | ||
| 176 | |||
| 177 | // Only accept keys defined in defaultSettings | ||
| 178 | this.settings = this.defaultSettings; | ||
| 179 | |||
| 180 | for (const key in settings) { | ||
| 181 | if (key in this.settings) { | ||
| 182 | this.settings[key] = settings[key]; | ||
| 183 | } else { | ||
| 184 | console.debug(`Ignoring non-user-configurable setting: ${key}`); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | // Set initial values from the settings | ||
| 189 | $('#vits_endpoint').val(this.settings.provider_endpoint); | ||
| 190 | $('#vits_lang').val(this.settings.lang); | ||
| 191 | $('#vits_format').val(this.settings.format); | ||
| 192 | $('#vits_length').val(this.settings.length); | ||
| 193 | $('#vits_noise').val(this.settings.noise); | ||
| 194 | $('#vits_noisew').val(this.settings.noisew); | ||
| 195 | $('#vits_segment_size').val(this.settings.segment_size); | ||
| 196 | $('#vits_streaming').prop('checked', this.settings.streaming); | ||
| 197 | $('#vits_dim_emotion').val(this.settings.dim_emotion); | ||
| 198 | $('#vits_sdp_ratio').val(this.settings.sdp_ratio); | ||
| 199 | $('#vits_emotion').val(this.settings.emotion); | ||
| 200 | $('#vits_text_prompt').val(this.settings.text_prompt); | ||
| 201 | $('#vits_style_text').val(this.settings.style_text); | ||
| 202 | $('#vits_style_weight').val(this.settings.style_weight); | ||
| 203 | |||
| 204 | // Update the UI to reflect changes | ||
| 205 | $('#vits_length_output').text(this.settings.length); | ||
| 206 | $('#vits_noise_output').text(this.settings.noise); | ||
| 207 | $('#vits_noisew_output').text(this.settings.noisew); | ||
| 208 | $('#vits_segment_size_output').text(this.settings.segment_size); | ||
| 209 | $('#vits_sdp_ratio_output').text(this.settings.sdp_ratio); | ||
| 210 | $('#vits_emotion_output').text(this.settings.emotion); | ||
| 211 | $('#vits_style_weight_output').text(this.settings.style_weight); | ||
| 212 | |||
| 213 | // Register input/change event listeners to update settings on user interaction | ||
| 214 | $('#vits_endpoint').on('input', () => { this.onSettingsChange(); }); | ||
| 215 | $('#vits_lang').on('change', () => { this.onSettingsChange(); }); | ||
| 216 | $('#vits_format').on('change', () => { this.onSettingsChange(); }); | ||
| 217 | $('#vits_length').on('change', () => { this.onSettingsChange(); }); | ||
| 218 | $('#vits_noise').on('change', () => { this.onSettingsChange(); }); | ||
| 219 | $('#vits_noisew').on('change', () => { this.onSettingsChange(); }); | ||
| 220 | $('#vits_segment_size').on('change', () => { this.onSettingsChange(); }); | ||
| 221 | $('#vits_streaming').on('change', () => { this.onSettingsChange(); }); | ||
| 222 | $('#vits_dim_emotion').on('change', () => { this.onSettingsChange(); }); | ||
| 223 | $('#vits_sdp_ratio').on('change', () => { this.onSettingsChange(); }); | ||
| 224 | $('#vits_emotion').on('change', () => { this.onSettingsChange(); }); | ||
| 225 | $('#vits_text_prompt').on('change', () => { this.onSettingsChange(); }); | ||
| 226 | $('#vits_style_text').on('change', () => { this.onSettingsChange(); }); | ||
| 227 | $('#vits_style_weight').on('change', () => { this.onSettingsChange(); }); | ||
| 228 | |||
| 229 | await this.checkReady(); | ||
| 230 | |||
| 231 | console.info('VITS: Settings loaded'); | ||
| 232 | } | ||
| 233 | |||
| 234 | // Perform a simple readiness check by trying to fetch voiceIds | ||
| 235 | async checkReady() { | ||
| 236 | await Promise.allSettled([this.fetchTtsVoiceObjects(), this.changeTTSSettings()]); | ||
| 237 | } | ||
| 238 | |||
| 239 | async onRefreshClick() { | ||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 243 | //#################// | ||
| 244 | // TTS Interfaces // | ||
| 245 | //#################// | ||
| 246 | |||
| 247 | async getVoice(voiceName) { | ||
| 248 | if (this.voices.length == 0) { | ||
| 249 | this.voices = await this.fetchTtsVoiceObjects(); | ||
| 250 | } | ||
| 251 | const match = this.voices.filter( | ||
| 252 | v => v.name == voiceName, | ||
| 253 | )[0]; | ||
| 254 | if (!match) { | ||
| 255 | throw `TTS Voice name ${voiceName} not found`; | ||
| 256 | } | ||
| 257 | return match; | ||
| 258 | } | ||
| 259 | |||
| 260 | async getVoiceById(voiceId) { | ||
| 261 | if (this.voices.length == 0) { | ||
| 262 | this.voices = await this.fetchTtsVoiceObjects(); | ||
| 263 | } | ||
| 264 | const match = this.voices.filter( | ||
| 265 | v => v.voice_id == voiceId, | ||
| 266 | )[0]; | ||
| 267 | if (!match) { | ||
| 268 | throw `TTS Voice id ${voiceId} not found`; | ||
| 269 | } | ||
| 270 | return match; | ||
| 271 | } | ||
| 272 | |||
| 273 | async generateTts(text, voiceId) { | ||
| 274 | const response = await this.fetchTtsGeneration(text, voiceId); | ||
| 275 | return response; | ||
| 276 | } | ||
| 277 | |||
| 278 | //###########// | ||
| 279 | // API CALLS // | ||
| 280 | //###########// | ||
| 281 | async fetchTtsVoiceObjects() { | ||
| 282 | const response = await fetch(`${this.settings.provider_endpoint}/voice/speakers`); | ||
| 283 | if (!response.ok) { | ||
| 284 | throw new Error(`HTTP ${response.status}: ${await response.json()}`); | ||
| 285 | } | ||
| 286 | const jsonData = await response.json(); | ||
| 287 | const voices = []; | ||
| 288 | |||
| 289 | const addVoices = (modelType) => { | ||
| 290 | jsonData[modelType].forEach(voice => { | ||
| 291 | voices.push({ | ||
| 292 | name: `[${modelType}] ${voice.name} (${voice.lang})`, | ||
| 293 | voice_id: `${modelType}&${voice.id}`, | ||
| 294 | preview_url: false, | ||
| 295 | lang: voice.lang, | ||
| 296 | }); | ||
| 297 | }); | ||
| 298 | }; | ||
| 299 | for (const key in this.modelTypes) { | ||
| 300 | addVoices(this.modelTypes[key]); | ||
| 301 | } | ||
| 302 | |||
| 303 | this.voices = voices; // Assign to the class property | ||
| 304 | return voices; // Also return this list | ||
| 305 | } | ||
| 306 | |||
| 307 | // Each time a parameter is changed, we change the configuration | ||
| 308 | async changeTTSSettings() { | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Fetch TTS generation from the API. | ||
| 313 | * @param {string} inputText Text to generate TTS for | ||
| 314 | * @param {string} voiceId Voice ID to use (model_type&speaker_id)) | ||
| 315 | * @returns {Promise<Response|string>} Fetch response | ||
| 316 | */ | ||
| 317 | async fetchTtsGeneration(inputText, voiceId, lang = null, forceNoStreaming = false) { | ||
| 318 | console.info(`Generating new TTS for voice_id ${voiceId}`); | ||
| 319 | |||
| 320 | const streaming = !forceNoStreaming && this.settings.streaming; | ||
| 321 | const [model_type, speaker_id] = voiceId.split('&'); | ||
| 322 | const params = new URLSearchParams(); | ||
| 323 | params.append('text', inputText); | ||
| 324 | params.append('id', speaker_id); | ||
| 325 | if (streaming) { | ||
| 326 | params.append('streaming', streaming); | ||
| 327 | // Streaming response only supports MP3 | ||
| 328 | } | ||
| 329 | else { | ||
| 330 | params.append('format', this.settings.format); | ||
| 331 | } | ||
| 332 | params.append('lang', lang ?? this.settings.lang); | ||
| 333 | params.append('length', this.settings.length); | ||
| 334 | params.append('noise', this.settings.noise); | ||
| 335 | params.append('noisew', this.settings.noisew); | ||
| 336 | params.append('segment_size', this.settings.segment_size); | ||
| 337 | |||
| 338 | if (model_type == this.modelTypes.W2V2_VITS) { | ||
| 339 | params.append('emotion', this.settings.dim_emotion); | ||
| 340 | } | ||
| 341 | else if (model_type == this.modelTypes.BERT_VITS2) { | ||
| 342 | params.append('sdp_ratio', this.settings.sdp_ratio); | ||
| 343 | params.append('emotion', this.settings.emotion); | ||
| 344 | if (this.settings.text_prompt) { | ||
| 345 | params.append('text_prompt', this.settings.text_prompt); | ||
| 346 | } | ||
| 347 | if (this.settings.style_text) { | ||
| 348 | params.append('style_text', this.settings.style_text); | ||
| 349 | params.append('style_weight', this.settings.style_weight); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | const url = `${this.settings.provider_endpoint}/voice/${model_type.toLowerCase()}`; | ||
| 354 | |||
| 355 | if (streaming) { | ||
| 356 | return url + `?${params.toString()}`; | ||
| 357 | } | ||
| 358 | |||
| 359 | const response = await fetch( | ||
| 360 | url, | ||
| 361 | { | ||
| 362 | method: 'POST', | ||
| 363 | headers: { | ||
| 364 | 'Content-Type': 'application/x-www-form-urlencoded', | ||
| 365 | }, | ||
| 366 | body: params, | ||
| 367 | }, | ||
| 368 | ); | ||
| 369 | if (!response.ok) { | ||
| 370 | toastr.error(response.statusText, 'TTS Generation Failed'); | ||
| 371 | throw new Error(`HTTP ${response.status}: ${await response.text()}`); | ||
| 372 | } | ||
| 373 | return response; | ||
| 374 | } | ||
| 375 | |||
| 376 | /** | ||
| 377 | * Preview TTS for a given voice ID. | ||
| 378 | * @param {string} id Voice ID | ||
| 379 | */ | ||
| 380 | async previewTtsVoice(id) { | ||
| 381 | this.audioElement.pause(); | ||
| 382 | this.audioElement.currentTime = 0; | ||
| 383 | const voice = await this.getVoiceById(id); | ||
| 384 | const lang = voice.lang.includes(this.settings.lang) ? this.settings.lang : voice.lang[0]; | ||
| 385 | |||
| 386 | let lang_code = this.langKey2LangCode[lang]; | ||
| 387 | const text = getPreviewString(lang_code); | ||
| 388 | const response = await this.fetchTtsGeneration(text, id, lang, true); | ||
| 389 | if (typeof response != 'string') { | ||
| 390 | if (!response.ok) { | ||
| 391 | throw new Error(`HTTP ${response.status}: ${await response.text()}`); | ||
| 392 | } | ||
| 393 | const audio = await response.blob(); | ||
| 394 | const url = URL.createObjectURL(audio); | ||
| 395 | this.audioElement.src = url; | ||
| 396 | this.audioElement.play(); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | // Interface not used | ||
| 401 | async fetchTtsFromHistory(history_item_id) { | ||
| 402 | return Promise.resolve(history_item_id); | ||
| 403 | } | ||
| 404 | } | ||
| @@ -38,13 +38,13 @@ import { | |||
| 38 | system_message_types, | 38 | system_message_types, |
| 39 | this_chid, | 39 | this_chid, |
| 40 | } from '../script.js'; | 40 | } from '../script.js'; |
| 41 | import { PARSER_FLAG, SlashCommandParser } from './slash-commands/SlashCommandParser.js'; | 41 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 42 | import { SlashCommandParserError } from './slash-commands/SlashCommandParserError.js'; | 42 | import { SlashCommandParserError } from './slash-commands/SlashCommandParserError.js'; |
| 43 | import { getMessageTimeStamp } from './RossAscends-mods.js'; | 43 | import { getMessageTimeStamp } from './RossAscends-mods.js'; |
| 44 | import { hideChatMessageRange } from './chats.js'; | 44 | import { hideChatMessageRange } from './chats.js'; |
| 45 | import { extension_settings, getContext, saveMetadataDebounced } from './extensions.js'; | 45 | import { getContext, saveMetadataDebounced } from './extensions.js'; |
| 46 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; | 46 | import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; |
| 47 | import { findGroupMemberId, getGroupMembers, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js'; | 47 | import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js'; |
| 48 | import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js'; | 48 | import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js'; |
| 49 | import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; | 49 | import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js'; |
| 50 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; | 50 | import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; |
| @@ -53,7 +53,6 @@ import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCoun | |||
| 53 | import { debounce, delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; | 53 | import { debounce, delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; |
| 54 | import { registerVariableCommands, resolveVariable } from './variables.js'; | 54 | import { registerVariableCommands, resolveVariable } from './variables.js'; |
| 55 | import { background_settings } from './backgrounds.js'; | 55 | import { background_settings } from './backgrounds.js'; |
| 56 | import { SlashCommandScope } from './slash-commands/SlashCommandScope.js'; | ||
| 57 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; | 56 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; |
| 58 | import { SlashCommandClosureResult } from './slash-commands/SlashCommandClosureResult.js'; | 57 | import { SlashCommandClosureResult } from './slash-commands/SlashCommandClosureResult.js'; |
| 59 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; | 58 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| @@ -75,78 +74,79 @@ export const parser = new SlashCommandParser(); | |||
| 75 | const registerSlashCommand = SlashCommandParser.addCommand.bind(SlashCommandParser); | 74 | const registerSlashCommand = SlashCommandParser.addCommand.bind(SlashCommandParser); |
| 76 | const getSlashCommandsHelp = parser.getHelpString.bind(parser); | 75 | const getSlashCommandsHelp = parser.getHelpString.bind(parser); |
| 77 | 76 | ||
| 78 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 77 | export function initDefaultSlashCommands() { |
| 79 | name: '?', | 78 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 80 | callback: helpCommandCallback, | 79 | name: '?', |
| 81 | aliases: ['help'], | 80 | callback: helpCommandCallback, |
| 82 | unnamedArgumentList: [SlashCommandArgument.fromProps({ | 81 | aliases: ['help'], |
| 83 | description: 'help topic', | 82 | unnamedArgumentList: [SlashCommandArgument.fromProps({ |
| 84 | typeList: [ARGUMENT_TYPE.STRING], | 83 | description: 'help topic', |
| 85 | enumList: [ | ||
| 86 | new SlashCommandEnumValue('slash', 'slash commands (STscript)', enumTypes.command, '/'), | ||
| 87 | new SlashCommandEnumValue('macros', '{{macros}} (text replacement)', enumTypes.macro, enumIcons.macro), | ||
| 88 | new SlashCommandEnumValue('format', 'chat/text formatting', enumTypes.name, '★'), | ||
| 89 | new SlashCommandEnumValue('hotkeys', 'keyboard shortcuts', enumTypes.enum, '⏎'), | ||
| 90 | ], | ||
| 91 | })], | ||
| 92 | helpString: 'Get help on macros, chat formatting and commands.', | ||
| 93 | })); | ||
| 94 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 95 | name: 'persona', | ||
| 96 | callback: setNameCallback, | ||
| 97 | namedArgumentList: [ | ||
| 98 | new SlashCommandNamedArgument( | ||
| 99 | 'mode', 'The mode for persona selection. ("lookup" = search for existing persona, "temp" = create a temporary name, set a temporary name, "all" = allow both in the same command)', | ||
| 100 | [ARGUMENT_TYPE.STRING], false, false, 'all', ['lookup', 'temp', 'all'], | ||
| 101 | ), | ||
| 102 | ], | ||
| 103 | unnamedArgumentList: [ | ||
| 104 | SlashCommandArgument.fromProps({ | ||
| 105 | description: 'persona name', | ||
| 106 | typeList: [ARGUMENT_TYPE.STRING], | 84 | typeList: [ARGUMENT_TYPE.STRING], |
| 107 | isRequired: true, | 85 | enumList: [ |
| 108 | enumProvider: commonEnumProviders.personas, | 86 | new SlashCommandEnumValue('slash', 'slash commands (STscript)', enumTypes.command, '/'), |
| 109 | }), | 87 | new SlashCommandEnumValue('macros', '{{macros}} (text replacement)', enumTypes.macro, enumIcons.macro), |
| 110 | ], | 88 | new SlashCommandEnumValue('format', 'chat/text formatting', enumTypes.name, '★'), |
| 111 | helpString: 'Selects the given persona with its name and avatar (by name or avatar url). If no matching persona exists, applies a temporary name.', | 89 | new SlashCommandEnumValue('hotkeys', 'keyboard shortcuts', enumTypes.enum, '⏎'), |
| 112 | aliases: ['name'], | 90 | ], |
| 113 | })); | 91 | })], |
| 114 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 92 | helpString: 'Get help on macros, chat formatting and commands.', |
| 115 | name: 'sync', | 93 | })); |
| 116 | callback: syncCallback, | 94 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 117 | helpString: 'Syncs the user persona in user-attributed messages in the current chat.', | 95 | name: 'persona', |
| 118 | })); | 96 | callback: setNameCallback, |
| 119 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 97 | namedArgumentList: [ |
| 120 | name: 'lock', | 98 | new SlashCommandNamedArgument( |
| 121 | callback: lockPersonaCallback, | 99 | 'mode', 'The mode for persona selection. ("lookup" = search for existing persona, "temp" = create a temporary name, set a temporary name, "all" = allow both in the same command)', |
| 122 | aliases: ['bind'], | 100 | [ARGUMENT_TYPE.STRING], false, false, 'all', ['lookup', 'temp', 'all'], |
| 123 | helpString: 'Locks/unlocks a persona (name and avatar) to the current chat', | 101 | ), |
| 124 | unnamedArgumentList: [ | 102 | ], |
| 125 | SlashCommandArgument.fromProps({ | 103 | unnamedArgumentList: [ |
| 126 | description: 'state', | 104 | SlashCommandArgument.fromProps({ |
| 127 | typeList: [ARGUMENT_TYPE.STRING], | 105 | description: 'persona name', |
| 128 | isRequired: true, | 106 | typeList: [ARGUMENT_TYPE.STRING], |
| 129 | defaultValue: 'toggle', | 107 | isRequired: true, |
| 130 | enumProvider: commonEnumProviders.boolean('onOffToggle'), | 108 | enumProvider: commonEnumProviders.personas, |
| 131 | }), | 109 | }), |
| 132 | ], | 110 | ], |
| 133 | })); | 111 | helpString: 'Selects the given persona with its name and avatar (by name or avatar url). If no matching persona exists, applies a temporary name.', |
| 134 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 112 | aliases: ['name'], |
| 135 | name: 'bg', | 113 | })); |
| 136 | callback: setBackgroundCallback, | 114 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 137 | aliases: ['background'], | 115 | name: 'sync', |
| 138 | returns: 'the current background', | 116 | callback: syncCallback, |
| 139 | unnamedArgumentList: [ | 117 | helpString: 'Syncs the user persona in user-attributed messages in the current chat.', |
| 140 | SlashCommandArgument.fromProps({ | 118 | })); |
| 141 | description: 'filename', | 119 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 142 | typeList: [ARGUMENT_TYPE.STRING], | 120 | name: 'lock', |
| 143 | isRequired: true, | 121 | callback: lockPersonaCallback, |
| 144 | enumProvider: () => [...document.querySelectorAll('.bg_example')] | 122 | aliases: ['bind'], |
| 145 | .map(it => new SlashCommandEnumValue(it.getAttribute('bgfile'))) | 123 | helpString: 'Locks/unlocks a persona (name and avatar) to the current chat', |
| 146 | .filter(it => it.value?.length), | 124 | unnamedArgumentList: [ |
| 147 | }), | 125 | SlashCommandArgument.fromProps({ |
| 148 | ], | 126 | description: 'state', |
| 149 | helpString: ` | 127 | typeList: [ARGUMENT_TYPE.STRING], |
| 128 | isRequired: true, | ||
| 129 | defaultValue: 'toggle', | ||
| 130 | enumProvider: commonEnumProviders.boolean('onOffToggle'), | ||
| 131 | }), | ||
| 132 | ], | ||
| 133 | })); | ||
| 134 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 135 | name: 'bg', | ||
| 136 | callback: setBackgroundCallback, | ||
| 137 | aliases: ['background'], | ||
| 138 | returns: 'the current background', | ||
| 139 | unnamedArgumentList: [ | ||
| 140 | SlashCommandArgument.fromProps({ | ||
| 141 | description: 'filename', | ||
| 142 | typeList: [ARGUMENT_TYPE.STRING], | ||
| 143 | isRequired: true, | ||
| 144 | enumProvider: () => [...document.querySelectorAll('.bg_example')] | ||
| 145 | .map(it => new SlashCommandEnumValue(it.getAttribute('bgfile'))) | ||
| 146 | .filter(it => it.value?.length), | ||
| 147 | }), | ||
| 148 | ], | ||
| 149 | helpString: ` | ||
| 150 | <div> | 150 | <div> |
| 151 | Sets a background according to the provided filename. Partial names allowed. | 151 | Sets a background according to the provided filename. Partial names allowed. |
| 152 | </div> | 152 | </div> |
| @@ -159,35 +159,35 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 159 | </ul> | 159 | </ul> |
| 160 | </div> | 160 | </div> |
| 161 | `, | 161 | `, |
| 162 | })); | 162 | })); |
| 163 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 163 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 164 | name: 'sendas', | 164 | name: 'sendas', |
| 165 | callback: sendMessageAs, | 165 | callback: sendMessageAs, |
| 166 | namedArgumentList: [ | 166 | namedArgumentList: [ |
| 167 | SlashCommandNamedArgument.fromProps({ | 167 | SlashCommandNamedArgument.fromProps({ |
| 168 | name: 'name', | 168 | name: 'name', |
| 169 | description: 'Character name', | 169 | description: 'Character name', |
| 170 | typeList: [ARGUMENT_TYPE.STRING], | 170 | typeList: [ARGUMENT_TYPE.STRING], |
| 171 | isRequired: true, | 171 | isRequired: true, |
| 172 | enumProvider: commonEnumProviders.characters('character'), | 172 | enumProvider: commonEnumProviders.characters('character'), |
| 173 | forceEnum: false, | 173 | forceEnum: false, |
| 174 | }), | 174 | }), |
| 175 | new SlashCommandNamedArgument( | 175 | new SlashCommandNamedArgument( |
| 176 | 'compact', 'Use compact layout', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', | 176 | 'compact', 'Use compact layout', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', |
| 177 | ), | 177 | ), |
| 178 | SlashCommandNamedArgument.fromProps({ | 178 | SlashCommandNamedArgument.fromProps({ |
| 179 | name: 'at', | 179 | name: 'at', |
| 180 | description: 'position to insert the message', | 180 | description: 'position to insert the message (index-based, corresponding to message id). If not set, the message will be inserted at the end of the chat.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will insert the message right before the last message in chat.', |
| 181 | typeList: [ARGUMENT_TYPE.NUMBER], | 181 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 182 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 182 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 183 | }), | 183 | }), |
| 184 | ], | 184 | ], |
| 185 | unnamedArgumentList: [ | 185 | unnamedArgumentList: [ |
| 186 | new SlashCommandArgument( | 186 | new SlashCommandArgument( |
| 187 | 'text', [ARGUMENT_TYPE.STRING], true, | 187 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 188 | ), | 188 | ), |
| 189 | ], | 189 | ], |
| 190 | helpString: ` | 190 | helpString: ` |
| 191 | <div> | 191 | <div> |
| 192 | Sends a message as a specific character. Uses the character avatar if it exists in the characters list. | 192 | Sends a message as a specific character. Uses the character avatar if it exists in the characters list. |
| 193 | </div> | 193 | </div> |
| @@ -204,33 +204,33 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 204 | If "compact" is set to true, the message is sent using a compact layout. | 204 | If "compact" is set to true, the message is sent using a compact layout. |
| 205 | </div> | 205 | </div> |
| 206 | `, | 206 | `, |
| 207 | })); | 207 | })); |
| 208 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 208 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 209 | name: 'sys', | 209 | name: 'sys', |
| 210 | callback: sendNarratorMessage, | 210 | callback: sendNarratorMessage, |
| 211 | aliases: ['nar'], | 211 | aliases: ['nar'], |
| 212 | namedArgumentList: [ | 212 | namedArgumentList: [ |
| 213 | new SlashCommandNamedArgument( | 213 | new SlashCommandNamedArgument( |
| 214 | 'compact', | 214 | 'compact', |
| 215 | 'compact layout', | 215 | 'compact layout', |
| 216 | [ARGUMENT_TYPE.BOOLEAN], | 216 | [ARGUMENT_TYPE.BOOLEAN], |
| 217 | false, | 217 | false, |
| 218 | false, | 218 | false, |
| 219 | 'false', | 219 | 'false', |
| 220 | ), | 220 | ), |
| 221 | SlashCommandNamedArgument.fromProps({ | 221 | SlashCommandNamedArgument.fromProps({ |
| 222 | name: 'at', | 222 | name: 'at', |
| 223 | description: 'position to insert the message', | 223 | description: 'position to insert the message (index-based, corresponding to message id). If not set, the message will be inserted at the end of the chat.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will insert the message right before the last message in chat.', |
| 224 | typeList: [ARGUMENT_TYPE.NUMBER], | 224 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 225 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 225 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 226 | }), | 226 | }), |
| 227 | ], | 227 | ], |
| 228 | unnamedArgumentList: [ | 228 | unnamedArgumentList: [ |
| 229 | new SlashCommandArgument( | 229 | new SlashCommandArgument( |
| 230 | 'text', [ARGUMENT_TYPE.STRING], true, | 230 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 231 | ), | 231 | ), |
| 232 | ], | 232 | ], |
| 233 | helpString: ` | 233 | helpString: ` |
| 234 | <div> | 234 | <div> |
| 235 | Sends a message as a system narrator. | 235 | Sends a message as a system narrator. |
| 236 | </div> | 236 | </div> |
| @@ -249,44 +249,44 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 249 | </ul> | 249 | </ul> |
| 250 | </div> | 250 | </div> |
| 251 | `, | 251 | `, |
| 252 | })); | 252 | })); |
| 253 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 253 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 254 | name: 'sysname', | 254 | name: 'sysname', |
| 255 | callback: setNarratorName, | 255 | callback: setNarratorName, |
| 256 | unnamedArgumentList: [ | 256 | unnamedArgumentList: [ |
| 257 | new SlashCommandArgument( | 257 | new SlashCommandArgument( |
| 258 | 'name', [ARGUMENT_TYPE.STRING], false, | 258 | 'name', [ARGUMENT_TYPE.STRING], false, |
| 259 | ), | 259 | ), |
| 260 | ], | 260 | ], |
| 261 | helpString: 'Sets a name for future system narrator messages in this chat (display only). Default: System. Leave empty to reset.', | 261 | helpString: 'Sets a name for future system narrator messages in this chat (display only). Default: System. Leave empty to reset.', |
| 262 | })); | 262 | })); |
| 263 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 263 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 264 | name: 'comment', | 264 | name: 'comment', |
| 265 | callback: sendCommentMessage, | 265 | callback: sendCommentMessage, |
| 266 | namedArgumentList: [ | 266 | namedArgumentList: [ |
| 267 | new SlashCommandNamedArgument( | 267 | new SlashCommandNamedArgument( |
| 268 | 'compact', | 268 | 'compact', |
| 269 | 'Whether to use a compact layout', | 269 | 'Whether to use a compact layout', |
| 270 | [ARGUMENT_TYPE.BOOLEAN], | 270 | [ARGUMENT_TYPE.BOOLEAN], |
| 271 | false, | 271 | false, |
| 272 | false, | 272 | false, |
| 273 | 'false', | 273 | 'false', |
| 274 | ), | 274 | ), |
| 275 | SlashCommandNamedArgument.fromProps({ | 275 | SlashCommandNamedArgument.fromProps({ |
| 276 | name: 'at', | 276 | name: 'at', |
| 277 | description: 'position to insert the message', | 277 | description: 'position to insert the message (index-based, corresponding to message id). If not set, the message will be inserted at the end of the chat.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will insert the message right before the last message in chat.', |
| 278 | typeList: [ARGUMENT_TYPE.NUMBER], | 278 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 279 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 279 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 280 | }), | 280 | }), |
| 281 | ], | 281 | ], |
| 282 | unnamedArgumentList: [ | 282 | unnamedArgumentList: [ |
| 283 | new SlashCommandArgument( | 283 | new SlashCommandArgument( |
| 284 | 'text', | 284 | 'text', |
| 285 | [ARGUMENT_TYPE.STRING], | 285 | [ARGUMENT_TYPE.STRING], |
| 286 | true, | 286 | true, |
| 287 | ), | 287 | ), |
| 288 | ], | 288 | ], |
| 289 | helpString: ` | 289 | helpString: ` |
| 290 | <div> | 290 | <div> |
| 291 | Adds a note/comment message not part of the chat. | 291 | Adds a note/comment message not part of the chat. |
| 292 | </div> | 292 | </div> |
| @@ -305,35 +305,35 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 305 | </ul> | 305 | </ul> |
| 306 | </div> | 306 | </div> |
| 307 | `, | 307 | `, |
| 308 | })); | 308 | })); |
| 309 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 309 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 310 | name: 'single', | 310 | name: 'single', |
| 311 | callback: setStoryModeCallback, | 311 | callback: setStoryModeCallback, |
| 312 | aliases: ['story'], | 312 | aliases: ['story'], |
| 313 | helpString: 'Sets the message style to single document mode without names or avatars visible.', | 313 | helpString: 'Sets the message style to single document mode without names or avatars visible.', |
| 314 | })); | 314 | })); |
| 315 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 315 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 316 | name: 'bubble', | 316 | name: 'bubble', |
| 317 | callback: setBubbleModeCallback, | 317 | callback: setBubbleModeCallback, |
| 318 | aliases: ['bubbles'], | 318 | aliases: ['bubbles'], |
| 319 | helpString: 'Sets the message style to bubble chat mode.', | 319 | helpString: 'Sets the message style to bubble chat mode.', |
| 320 | })); | 320 | })); |
| 321 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 321 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 322 | name: 'flat', | 322 | name: 'flat', |
| 323 | callback: setFlatModeCallback, | 323 | callback: setFlatModeCallback, |
| 324 | aliases: ['default'], | 324 | aliases: ['default'], |
| 325 | helpString: 'Sets the message style to flat chat mode.', | 325 | helpString: 'Sets the message style to flat chat mode.', |
| 326 | })); | 326 | })); |
| 327 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 327 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 328 | name: 'continue', | 328 | name: 'continue', |
| 329 | callback: continueChatCallback, | 329 | callback: continueChatCallback, |
| 330 | aliases: ['cont'], | 330 | aliases: ['cont'], |
| 331 | unnamedArgumentList: [ | 331 | unnamedArgumentList: [ |
| 332 | new SlashCommandArgument( | 332 | new SlashCommandArgument( |
| 333 | 'prompt', [ARGUMENT_TYPE.STRING], false, | 333 | 'prompt', [ARGUMENT_TYPE.STRING], false, |
| 334 | ), | 334 | ), |
| 335 | ], | 335 | ], |
| 336 | helpString: ` | 336 | helpString: ` |
| 337 | <div> | 337 | <div> |
| 338 | Continues the last message in the chat, with an optional additional prompt. | 338 | Continues the last message in the chat, with an optional additional prompt. |
| 339 | </div> | 339 | </div> |
| @@ -351,87 +351,87 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 351 | </ul> | 351 | </ul> |
| 352 | </div> | 352 | </div> |
| 353 | `, | 353 | `, |
| 354 | })); | 354 | })); |
| 355 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 355 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 356 | name: 'go', | 356 | name: 'go', |
| 357 | callback: goToCharacterCallback, | 357 | callback: goToCharacterCallback, |
| 358 | unnamedArgumentList: [ | 358 | unnamedArgumentList: [ |
| 359 | SlashCommandArgument.fromProps({ | 359 | SlashCommandArgument.fromProps({ |
| 360 | description: 'name', | 360 | description: 'name', |
| 361 | typeList: [ARGUMENT_TYPE.STRING], | 361 | typeList: [ARGUMENT_TYPE.STRING], |
| 362 | isRequired: true, | 362 | isRequired: true, |
| 363 | enumProvider: commonEnumProviders.characters('all'), | 363 | enumProvider: commonEnumProviders.characters('all'), |
| 364 | }), | 364 | }), |
| 365 | ], | 365 | ], |
| 366 | helpString: 'Opens up a chat with the character or group by its name', | 366 | helpString: 'Opens up a chat with the character or group by its name', |
| 367 | aliases: ['char'], | 367 | aliases: ['char'], |
| 368 | })); | 368 | })); |
| 369 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 369 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 370 | name: 'rename-char', | 370 | name: 'rename-char', |
| 371 | /** @param {{silent: string, chats: string}} options @param {string} name */ | 371 | /** @param {{silent: string, chats: string}} options @param {string} name */ |
| 372 | callback: async ({ silent = 'true', chats = null }, name) => { | 372 | callback: async ({ silent = 'true', chats = null }, name) => { |
| 373 | const renamed = await renameCharacter(name, { silent: isTrueBoolean(silent), renameChats: chats !== null ? isTrueBoolean(chats) : null }); | 373 | const renamed = await renameCharacter(name, { silent: isTrueBoolean(silent), renameChats: chats !== null ? isTrueBoolean(chats) : null }); |
| 374 | return String(renamed); | 374 | return String(renamed); |
| 375 | }, | 375 | }, |
| 376 | returns: 'true/false - Whether the rename was successful', | 376 | returns: 'true/false - Whether the rename was successful', |
| 377 | namedArgumentList: [ | 377 | namedArgumentList: [ |
| 378 | new SlashCommandNamedArgument( | 378 | new SlashCommandNamedArgument( |
| 379 | 'silent', 'Hide any blocking popups. (if false, the name is optional. If not supplied, a popup asking for it will appear)', [ARGUMENT_TYPE.BOOLEAN], false, false, 'true', | 379 | 'silent', 'Hide any blocking popups. (if false, the name is optional. If not supplied, a popup asking for it will appear)', [ARGUMENT_TYPE.BOOLEAN], false, false, 'true', |
| 380 | ), | 380 | ), |
| 381 | new SlashCommandNamedArgument( | 381 | new SlashCommandNamedArgument( |
| 382 | 'chats', 'Rename char in all previous chats', [ARGUMENT_TYPE.BOOLEAN], false, false, '<null>', | 382 | 'chats', 'Rename char in all previous chats', [ARGUMENT_TYPE.BOOLEAN], false, false, '<null>', |
| 383 | ), | 383 | ), |
| 384 | ], | 384 | ], |
| 385 | unnamedArgumentList: [ | 385 | unnamedArgumentList: [ |
| 386 | new SlashCommandArgument( | 386 | new SlashCommandArgument( |
| 387 | 'new char name', [ARGUMENT_TYPE.STRING], true, | 387 | 'new char name', [ARGUMENT_TYPE.STRING], true, |
| 388 | ), | 388 | ), |
| 389 | ], | 389 | ], |
| 390 | helpString: 'Renames the current character.', | 390 | helpString: 'Renames the current character.', |
| 391 | })); | 391 | })); |
| 392 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 392 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 393 | name: 'sysgen', | 393 | name: 'sysgen', |
| 394 | callback: generateSystemMessage, | 394 | callback: generateSystemMessage, |
| 395 | unnamedArgumentList: [ | 395 | unnamedArgumentList: [ |
| 396 | new SlashCommandArgument( | 396 | new SlashCommandArgument( |
| 397 | 'prompt', [ARGUMENT_TYPE.STRING], true, | 397 | 'prompt', [ARGUMENT_TYPE.STRING], true, |
| 398 | ), | 398 | ), |
| 399 | ], | 399 | ], |
| 400 | helpString: 'Generates a system message using a specified prompt.', | 400 | helpString: 'Generates a system message using a specified prompt.', |
| 401 | })); | 401 | })); |
| 402 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 402 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 403 | name: 'ask', | 403 | name: 'ask', |
| 404 | callback: askCharacter, | 404 | callback: askCharacter, |
| 405 | namedArgumentList: [ | 405 | namedArgumentList: [ |
| 406 | SlashCommandNamedArgument.fromProps({ | 406 | SlashCommandNamedArgument.fromProps({ |
| 407 | name: 'name', | 407 | name: 'name', |
| 408 | description: 'character name', | 408 | description: 'character name', |
| 409 | typeList: [ARGUMENT_TYPE.STRING], | 409 | typeList: [ARGUMENT_TYPE.STRING], |
| 410 | isRequired: true, | 410 | isRequired: true, |
| 411 | enumProvider: commonEnumProviders.characters('character'), | 411 | enumProvider: commonEnumProviders.characters('character'), |
| 412 | }), | 412 | }), |
| 413 | ], | 413 | ], |
| 414 | unnamedArgumentList: [ | 414 | unnamedArgumentList: [ |
| 415 | new SlashCommandArgument( | 415 | new SlashCommandArgument( |
| 416 | 'prompt', [ARGUMENT_TYPE.STRING], true, false, | 416 | 'prompt', [ARGUMENT_TYPE.STRING], true, false, |
| 417 | ), | 417 | ), |
| 418 | ], | 418 | ], |
| 419 | helpString: 'Asks a specified character card a prompt. Character name must be provided in a named argument.', | 419 | helpString: 'Asks a specified character card a prompt. Character name must be provided in a named argument.', |
| 420 | })); | 420 | })); |
| 421 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 421 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 422 | name: 'delname', | 422 | name: 'delname', |
| 423 | callback: deleteMessagesByNameCallback, | 423 | callback: deleteMessagesByNameCallback, |
| 424 | namedArgumentList: [], | 424 | namedArgumentList: [], |
| 425 | unnamedArgumentList: [ | 425 | unnamedArgumentList: [ |
| 426 | SlashCommandArgument.fromProps({ | 426 | SlashCommandArgument.fromProps({ |
| 427 | description: 'name', | 427 | description: 'name', |
| 428 | typeList: [ARGUMENT_TYPE.STRING], | 428 | typeList: [ARGUMENT_TYPE.STRING], |
| 429 | isRequired: true, | 429 | isRequired: true, |
| 430 | enumProvider: commonEnumProviders.characters('character'), | 430 | enumProvider: commonEnumProviders.characters('character'), |
| 431 | }), | 431 | }), |
| 432 | ], | 432 | ], |
| 433 | aliases: ['cancel'], | 433 | aliases: ['cancel'], |
| 434 | helpString: ` | 434 | helpString: ` |
| 435 | <div> | 435 | <div> |
| 436 | Deletes all messages attributed to a specified name. | 436 | Deletes all messages attributed to a specified name. |
| 437 | </div> | 437 | </div> |
| @@ -444,41 +444,41 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 444 | </ul> | 444 | </ul> |
| 445 | </div> | 445 | </div> |
| 446 | `, | 446 | `, |
| 447 | })); | 447 | })); |
| 448 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 448 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 449 | name: 'send', | 449 | name: 'send', |
| 450 | callback: sendUserMessageCallback, | 450 | callback: sendUserMessageCallback, |
| 451 | namedArgumentList: [ | 451 | namedArgumentList: [ |
| 452 | new SlashCommandNamedArgument( | 452 | new SlashCommandNamedArgument( |
| 453 | 'compact', | 453 | 'compact', |
| 454 | 'whether to use a compact layout', | 454 | 'whether to use a compact layout', |
| 455 | [ARGUMENT_TYPE.BOOLEAN], | 455 | [ARGUMENT_TYPE.BOOLEAN], |
| 456 | false, | 456 | false, |
| 457 | false, | 457 | false, |
| 458 | 'false', | 458 | 'false', |
| 459 | ), | 459 | ), |
| 460 | SlashCommandNamedArgument.fromProps({ | 460 | SlashCommandNamedArgument.fromProps({ |
| 461 | name: 'at', | 461 | name: 'at', |
| 462 | description: 'position to insert the message', | 462 | description: 'position to insert the message (index-based, corresponding to message id). If not set, the message will be inserted at the end of the chat.\nNegative values are accepted and will work similarly to how \'depth\' usually works. For example, -1 will insert the message right before the last message in chat.', |
| 463 | typeList: [ARGUMENT_TYPE.NUMBER], | 463 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 464 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 464 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 465 | }), | 465 | }), |
| 466 | SlashCommandNamedArgument.fromProps({ | 466 | SlashCommandNamedArgument.fromProps({ |
| 467 | name: 'name', | 467 | name: 'name', |
| 468 | description: 'display name', | 468 | description: 'display name', |
| 469 | typeList: [ARGUMENT_TYPE.STRING], | 469 | typeList: [ARGUMENT_TYPE.STRING], |
| 470 | defaultValue: '{{user}}', | 470 | defaultValue: '{{user}}', |
| 471 | enumProvider: commonEnumProviders.characters('character'), | 471 | enumProvider: commonEnumProviders.characters('character'), |
| 472 | }), | 472 | }), |
| 473 | ], | 473 | ], |
| 474 | unnamedArgumentList: [ | 474 | unnamedArgumentList: [ |
| 475 | new SlashCommandArgument( | 475 | new SlashCommandArgument( |
| 476 | 'text', | 476 | 'text', |
| 477 | [ARGUMENT_TYPE.STRING], | 477 | [ARGUMENT_TYPE.STRING], |
| 478 | true, | 478 | true, |
| 479 | ), | 479 | ), |
| 480 | ], | 480 | ], |
| 481 | helpString: ` | 481 | helpString: ` |
| 482 | <div> | 482 | <div> |
| 483 | Adds a user message to the chat log without triggering a generation. | 483 | Adds a user message to the chat log without triggering a generation. |
| 484 | </div> | 484 | </div> |
| @@ -500,29 +500,29 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 500 | </ul> | 500 | </ul> |
| 501 | </div> | 501 | </div> |
| 502 | `, | 502 | `, |
| 503 | })); | 503 | })); |
| 504 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 504 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 505 | name: 'trigger', | 505 | name: 'trigger', |
| 506 | callback: triggerGenerationCallback, | 506 | callback: triggerGenerationCallback, |
| 507 | namedArgumentList: [ | 507 | namedArgumentList: [ |
| 508 | new SlashCommandNamedArgument( | 508 | new SlashCommandNamedArgument( |
| 509 | 'await', | 509 | 'await', |
| 510 | 'Whether to await for the triggered generation before continuing', | 510 | 'Whether to await for the triggered generation before continuing', |
| 511 | [ARGUMENT_TYPE.BOOLEAN], | 511 | [ARGUMENT_TYPE.BOOLEAN], |
| 512 | false, | 512 | false, |
| 513 | false, | 513 | false, |
| 514 | 'false', | 514 | 'false', |
| 515 | ), | 515 | ), |
| 516 | ], | 516 | ], |
| 517 | unnamedArgumentList: [ | 517 | unnamedArgumentList: [ |
| 518 | SlashCommandArgument.fromProps({ | 518 | SlashCommandArgument.fromProps({ |
| 519 | description: 'group member index (starts with 0) or name', | 519 | description: 'group member index (starts with 0) or name', |
| 520 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 520 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 521 | isRequired: false, | 521 | isRequired: false, |
| 522 | enumProvider: commonEnumProviders.groupMembers(), | 522 | enumProvider: commonEnumProviders.groupMembers(), |
| 523 | }), | 523 | }), |
| 524 | ], | 524 | ], |
| 525 | helpString: ` | 525 | helpString: ` |
| 526 | <div> | 526 | <div> |
| 527 | Triggers a message generation. If in group, can trigger a message for the specified group member index or name. | 527 | Triggers a message generation. If in group, can trigger a message for the specified group member index or name. |
| 528 | </div> | 528 | </div> |
| @@ -530,74 +530,74 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 530 | If <code>await=true</code> named argument is passed, the command will await for the triggered generation before continuing. | 530 | If <code>await=true</code> named argument is passed, the command will await for the triggered generation before continuing. |
| 531 | </div> | 531 | </div> |
| 532 | `, | 532 | `, |
| 533 | })); | 533 | })); |
| 534 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 534 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 535 | name: 'hide', | 535 | name: 'hide', |
| 536 | callback: hideMessageCallback, | 536 | callback: hideMessageCallback, |
| 537 | unnamedArgumentList: [ | 537 | unnamedArgumentList: [ |
| 538 | SlashCommandArgument.fromProps({ | 538 | SlashCommandArgument.fromProps({ |
| 539 | description: 'message index (starts with 0) or range', | 539 | description: 'message index (starts with 0) or range', |
| 540 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], | 540 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], |
| 541 | isRequired: true, | 541 | isRequired: true, |
| 542 | enumProvider: commonEnumProviders.messages(), | 542 | enumProvider: commonEnumProviders.messages(), |
| 543 | }), | 543 | }), |
| 544 | ], | 544 | ], |
| 545 | helpString: 'Hides a chat message from the prompt.', | 545 | helpString: 'Hides a chat message from the prompt.', |
| 546 | })); | 546 | })); |
| 547 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 547 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 548 | name: 'unhide', | 548 | name: 'unhide', |
| 549 | callback: unhideMessageCallback, | 549 | callback: unhideMessageCallback, |
| 550 | unnamedArgumentList: [ | 550 | unnamedArgumentList: [ |
| 551 | SlashCommandArgument.fromProps({ | 551 | SlashCommandArgument.fromProps({ |
| 552 | description: 'message index (starts with 0) or range', | 552 | description: 'message index (starts with 0) or range', |
| 553 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], | 553 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], |
| 554 | isRequired: true, | 554 | isRequired: true, |
| 555 | enumProvider: commonEnumProviders.messages(), | 555 | enumProvider: commonEnumProviders.messages(), |
| 556 | }), | 556 | }), |
| 557 | ], | 557 | ], |
| 558 | helpString: 'Unhides a message from the prompt.', | 558 | helpString: 'Unhides a message from the prompt.', |
| 559 | })); | 559 | })); |
| 560 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 560 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 561 | name: 'member-disable', | 561 | name: 'member-disable', |
| 562 | callback: disableGroupMemberCallback, | 562 | callback: disableGroupMemberCallback, |
| 563 | aliases: ['disable', 'disablemember', 'memberdisable'], | 563 | aliases: ['disable', 'disablemember', 'memberdisable'], |
| 564 | unnamedArgumentList: [ | 564 | unnamedArgumentList: [ |
| 565 | SlashCommandArgument.fromProps({ | 565 | SlashCommandArgument.fromProps({ |
| 566 | description: 'member index (starts with 0) or name', | 566 | description: 'member index (starts with 0) or name', |
| 567 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 567 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 568 | isRequired: true, | 568 | isRequired: true, |
| 569 | enumProvider: commonEnumProviders.groupMembers(), | 569 | enumProvider: commonEnumProviders.groupMembers(), |
| 570 | }), | 570 | }), |
| 571 | ], | 571 | ], |
| 572 | helpString: 'Disables a group member from being drafted for replies.', | 572 | helpString: 'Disables a group member from being drafted for replies.', |
| 573 | })); | 573 | })); |
| 574 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 574 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 575 | name: 'member-enable', | 575 | name: 'member-enable', |
| 576 | aliases: ['enable', 'enablemember', 'memberenable'], | 576 | aliases: ['enable', 'enablemember', 'memberenable'], |
| 577 | callback: enableGroupMemberCallback, | 577 | callback: enableGroupMemberCallback, |
| 578 | unnamedArgumentList: [ | 578 | unnamedArgumentList: [ |
| 579 | SlashCommandArgument.fromProps({ | 579 | SlashCommandArgument.fromProps({ |
| 580 | description: 'member index (starts with 0) or name', | 580 | description: 'member index (starts with 0) or name', |
| 581 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 581 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 582 | isRequired: true, | 582 | isRequired: true, |
| 583 | enumProvider: commonEnumProviders.groupMembers(), | 583 | enumProvider: commonEnumProviders.groupMembers(), |
| 584 | }), | 584 | }), |
| 585 | ], | 585 | ], |
| 586 | helpString: 'Enables a group member to be drafted for replies.', | 586 | helpString: 'Enables a group member to be drafted for replies.', |
| 587 | })); | 587 | })); |
| 588 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 588 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 589 | name: 'member-add', | 589 | name: 'member-add', |
| 590 | callback: addGroupMemberCallback, | 590 | callback: addGroupMemberCallback, |
| 591 | aliases: ['addmember', 'memberadd'], | 591 | aliases: ['addmember', 'memberadd'], |
| 592 | unnamedArgumentList: [ | 592 | unnamedArgumentList: [ |
| 593 | SlashCommandArgument.fromProps({ | 593 | SlashCommandArgument.fromProps({ |
| 594 | description: 'character name', | 594 | description: 'character name', |
| 595 | typeList: [ARGUMENT_TYPE.STRING], | 595 | typeList: [ARGUMENT_TYPE.STRING], |
| 596 | isRequired: true, | 596 | isRequired: true, |
| 597 | enumProvider: () => selected_group ? commonEnumProviders.characters('character')() : [], | 597 | enumProvider: () => selected_group ? commonEnumProviders.characters('character')() : [], |
| 598 | }), | 598 | }), |
| 599 | ], | 599 | ], |
| 600 | helpString: ` | 600 | helpString: ` |
| 601 | <div> | 601 | <div> |
| 602 | Adds a new group member to the group chat. | 602 | Adds a new group member to the group chat. |
| 603 | </div> | 603 | </div> |
| @@ -610,20 +610,20 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 610 | </ul> | 610 | </ul> |
| 611 | </div> | 611 | </div> |
| 612 | `, | 612 | `, |
| 613 | })); | 613 | })); |
| 614 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 614 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 615 | name: 'member-remove', | 615 | name: 'member-remove', |
| 616 | callback: removeGroupMemberCallback, | 616 | callback: removeGroupMemberCallback, |
| 617 | aliases: ['removemember', 'memberremove'], | 617 | aliases: ['removemember', 'memberremove'], |
| 618 | unnamedArgumentList: [ | 618 | unnamedArgumentList: [ |
| 619 | SlashCommandArgument.fromProps({ | 619 | SlashCommandArgument.fromProps({ |
| 620 | description: 'member index (starts with 0) or name', | 620 | description: 'member index (starts with 0) or name', |
| 621 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 621 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 622 | isRequired: true, | 622 | isRequired: true, |
| 623 | enumProvider: commonEnumProviders.groupMembers(), | 623 | enumProvider: commonEnumProviders.groupMembers(), |
| 624 | }), | 624 | }), |
| 625 | ], | 625 | ], |
| 626 | helpString: ` | 626 | helpString: ` |
| 627 | <div> | 627 | <div> |
| 628 | Removes a group member from the group chat. | 628 | Removes a group member from the group chat. |
| 629 | </div> | 629 | </div> |
| @@ -637,47 +637,47 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 637 | </ul> | 637 | </ul> |
| 638 | </div> | 638 | </div> |
| 639 | `, | 639 | `, |
| 640 | })); | 640 | })); |
| 641 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 641 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 642 | name: 'member-up', | 642 | name: 'member-up', |
| 643 | callback: moveGroupMemberUpCallback, | 643 | callback: moveGroupMemberUpCallback, |
| 644 | aliases: ['upmember', 'memberup'], | 644 | aliases: ['upmember', 'memberup'], |
| 645 | unnamedArgumentList: [ | 645 | unnamedArgumentList: [ |
| 646 | SlashCommandArgument.fromProps({ | 646 | SlashCommandArgument.fromProps({ |
| 647 | description: 'member index (starts with 0) or name', | 647 | description: 'member index (starts with 0) or name', |
| 648 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 648 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 649 | isRequired: true, | 649 | isRequired: true, |
| 650 | enumProvider: commonEnumProviders.groupMembers(), | 650 | enumProvider: commonEnumProviders.groupMembers(), |
| 651 | }), | 651 | }), |
| 652 | ], | 652 | ], |
| 653 | helpString: 'Moves a group member up in the group chat list.', | 653 | helpString: 'Moves a group member up in the group chat list.', |
| 654 | })); | 654 | })); |
| 655 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 655 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 656 | name: 'member-down', | 656 | name: 'member-down', |
| 657 | callback: moveGroupMemberDownCallback, | 657 | callback: moveGroupMemberDownCallback, |
| 658 | aliases: ['downmember', 'memberdown'], | 658 | aliases: ['downmember', 'memberdown'], |
| 659 | unnamedArgumentList: [ | 659 | unnamedArgumentList: [ |
| 660 | SlashCommandArgument.fromProps({ | 660 | SlashCommandArgument.fromProps({ |
| 661 | description: 'member index (starts with 0) or name', | 661 | description: 'member index (starts with 0) or name', |
| 662 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 662 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 663 | isRequired: true, | 663 | isRequired: true, |
| 664 | enumProvider: commonEnumProviders.groupMembers(), | 664 | enumProvider: commonEnumProviders.groupMembers(), |
| 665 | }), | 665 | }), |
| 666 | ], | 666 | ], |
| 667 | helpString: 'Moves a group member down in the group chat list.', | 667 | helpString: 'Moves a group member down in the group chat list.', |
| 668 | })); | 668 | })); |
| 669 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 669 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 670 | name: 'peek', | 670 | name: 'peek', |
| 671 | callback: peekCallback, | 671 | callback: peekCallback, |
| 672 | unnamedArgumentList: [ | 672 | unnamedArgumentList: [ |
| 673 | SlashCommandArgument.fromProps({ | 673 | SlashCommandArgument.fromProps({ |
| 674 | description: 'member index (starts with 0) or name', | 674 | description: 'member index (starts with 0) or name', |
| 675 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], | 675 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.STRING], |
| 676 | isRequired: true, | 676 | isRequired: true, |
| 677 | enumProvider: commonEnumProviders.groupMembers(), | 677 | enumProvider: commonEnumProviders.groupMembers(), |
| 678 | }), | 678 | }), |
| 679 | ], | 679 | ], |
| 680 | helpString: ` | 680 | helpString: ` |
| 681 | <div> | 681 | <div> |
| 682 | Shows a group member character card without switching chats. | 682 | Shows a group member character card without switching chats. |
| 683 | </div> | 683 | </div> |
| @@ -691,22 +691,22 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 691 | </ul> | 691 | </ul> |
| 692 | </div> | 692 | </div> |
| 693 | `, | 693 | `, |
| 694 | })); | 694 | })); |
| 695 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 695 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 696 | name: 'delswipe', | 696 | name: 'delswipe', |
| 697 | callback: deleteSwipeCallback, | 697 | callback: deleteSwipeCallback, |
| 698 | aliases: ['swipedel'], | 698 | aliases: ['swipedel'], |
| 699 | unnamedArgumentList: [ | 699 | unnamedArgumentList: [ |
| 700 | SlashCommandArgument.fromProps({ | 700 | SlashCommandArgument.fromProps({ |
| 701 | description: '1-based swipe id', | 701 | description: '1-based swipe id', |
| 702 | typeList: [ARGUMENT_TYPE.NUMBER], | 702 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 703 | isRequired: true, | 703 | isRequired: true, |
| 704 | enumProvider: () => Array.isArray(chat[chat.length - 1]?.swipes) ? | 704 | enumProvider: () => Array.isArray(chat[chat.length - 1]?.swipes) ? |
| 705 | chat[chat.length - 1].swipes.map((/** @type {string} */ swipe, /** @type {number} */ i) => new SlashCommandEnumValue(String(i + 1), swipe, enumTypes.enum, enumIcons.message)) | 705 | chat[chat.length - 1].swipes.map((/** @type {string} */ swipe, /** @type {number} */ i) => new SlashCommandEnumValue(String(i + 1), swipe, enumTypes.enum, enumIcons.message)) |
| 706 | : [], | 706 | : [], |
| 707 | }), | 707 | }), |
| 708 | ], | 708 | ], |
| 709 | helpString: ` | 709 | helpString: ` |
| 710 | <div> | 710 | <div> |
| 711 | Deletes a swipe from the last chat message. If swipe id is not provided, it deletes the current swipe. | 711 | Deletes a swipe from the last chat message. If swipe id is not provided, it deletes the current swipe. |
| 712 | </div> | 712 | </div> |
| @@ -724,34 +724,60 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 724 | </ul> | 724 | </ul> |
| 725 | </div> | 725 | </div> |
| 726 | `, | 726 | `, |
| 727 | })); | 727 | })); |
| 728 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 728 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 729 | name: 'echo', | 729 | name: 'echo', |
| 730 | callback: echoCallback, | 730 | callback: echoCallback, |
| 731 | returns: 'the text', | 731 | returns: 'the text', |
| 732 | namedArgumentList: [ | 732 | namedArgumentList: [ |
| 733 | new SlashCommandNamedArgument( | 733 | new SlashCommandNamedArgument( |
| 734 | 'title', 'title of the toast message', [ARGUMENT_TYPE.STRING], false, | 734 | 'title', 'title of the toast message', [ARGUMENT_TYPE.STRING], false, |
| 735 | ), | 735 | ), |
| 736 | SlashCommandNamedArgument.fromProps({ | 736 | SlashCommandNamedArgument.fromProps({ |
| 737 | name: 'severity', | 737 | name: 'severity', |
| 738 | description: 'severity level of the toast message', | 738 | description: 'severity level of the toast message', |
| 739 | typeList: [ARGUMENT_TYPE.STRING], | 739 | typeList: [ARGUMENT_TYPE.STRING], |
| 740 | defaultValue: 'info', | 740 | defaultValue: 'info', |
| 741 | enumProvider: () => [ | 741 | enumProvider: () => [ |
| 742 | new SlashCommandEnumValue('info', 'info', enumTypes.macro, 'ℹ️'), | 742 | new SlashCommandEnumValue('info', 'info', enumTypes.macro, 'ℹ️'), |
| 743 | new SlashCommandEnumValue('warning', 'warning', enumTypes.enum, '⚠️'), | 743 | new SlashCommandEnumValue('warning', 'warning', enumTypes.enum, '⚠️'), |
| 744 | new SlashCommandEnumValue('error', 'error', enumTypes.enum, '❗'), | 744 | new SlashCommandEnumValue('error', 'error', enumTypes.enum, '❗'), |
| 745 | new SlashCommandEnumValue('success', 'success', enumTypes.enum, '✅'), | 745 | new SlashCommandEnumValue('success', 'success', enumTypes.enum, '✅'), |
| 746 | ], | 746 | ], |
| 747 | }), | 747 | }), |
| 748 | ], | 748 | SlashCommandNamedArgument.fromProps({ |
| 749 | unnamedArgumentList: [ | 749 | name: 'timeout', |
| 750 | new SlashCommandArgument( | 750 | description: 'time in milliseconds to display the toast message. Set this and \'extendedTimeout\' to 0 to show indefinitely until dismissed.', |
| 751 | 'text', [ARGUMENT_TYPE.STRING], true, | 751 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 752 | ), | 752 | defaultValue: `${toastr.options.timeOut}`, |
| 753 | ], | 753 | }), |
| 754 | helpString: ` | 754 | SlashCommandNamedArgument.fromProps({ |
| 755 | name: 'extendedTimeout', | ||
| 756 | description: 'time in milliseconds to display the toast message. Set this and \'timeout\' to 0 to show indefinitely until dismissed.', | ||
| 757 | typeList: [ARGUMENT_TYPE.NUMBER], | ||
| 758 | defaultValue: `${toastr.options.extendedTimeOut}`, | ||
| 759 | }), | ||
| 760 | SlashCommandNamedArgument.fromProps({ | ||
| 761 | name: 'preventDuplicates', | ||
| 762 | description: 'prevent duplicate toasts with the same message from being displayed.', | ||
| 763 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 764 | defaultValue: 'false', | ||
| 765 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 766 | }), | ||
| 767 | SlashCommandNamedArgument.fromProps({ | ||
| 768 | name: 'awaitDismissal', | ||
| 769 | description: 'wait for the toast to be dismissed before continuing.', | ||
| 770 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 771 | defaultValue: 'false', | ||
| 772 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 773 | }), | ||
| 774 | ], | ||
| 775 | unnamedArgumentList: [ | ||
| 776 | new SlashCommandArgument( | ||
| 777 | 'text', [ARGUMENT_TYPE.STRING], true, | ||
| 778 | ), | ||
| 779 | ], | ||
| 780 | helpString: ` | ||
| 755 | <div> | 781 | <div> |
| 756 | Echoes the provided text to a toast message. Useful for pipes debugging. | 782 | Echoes the provided text to a toast message. Useful for pipes debugging. |
| 757 | </div> | 783 | </div> |
| @@ -764,42 +790,42 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 764 | </ul> | 790 | </ul> |
| 765 | </div> | 791 | </div> |
| 766 | `, | 792 | `, |
| 767 | })); | 793 | })); |
| 768 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 794 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 769 | name: 'gen', | 795 | name: 'gen', |
| 770 | callback: generateCallback, | 796 | callback: generateCallback, |
| 771 | returns: 'generated text', | 797 | returns: 'generated text', |
| 772 | namedArgumentList: [ | 798 | namedArgumentList: [ |
| 773 | new SlashCommandNamedArgument( | 799 | new SlashCommandNamedArgument( |
| 774 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), | 800 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), |
| 775 | ), | 801 | ), |
| 776 | SlashCommandNamedArgument.fromProps({ | 802 | SlashCommandNamedArgument.fromProps({ |
| 777 | name: 'name', | 803 | name: 'name', |
| 778 | description: 'in-prompt name for instruct mode', | 804 | description: 'in-prompt name for instruct mode', |
| 779 | typeList: [ARGUMENT_TYPE.STRING], | 805 | typeList: [ARGUMENT_TYPE.STRING], |
| 780 | defaultValue: 'System', | 806 | defaultValue: 'System', |
| 781 | enumProvider: () => [...commonEnumProviders.characters('character')(), new SlashCommandEnumValue('System', null, enumTypes.enum, enumIcons.assistant)], | 807 | enumProvider: () => [...commonEnumProviders.characters('character')(), new SlashCommandEnumValue('System', null, enumTypes.enum, enumIcons.assistant)], |
| 782 | forceEnum: false, | 808 | forceEnum: false, |
| 783 | }), | 809 | }), |
| 784 | new SlashCommandNamedArgument( | 810 | new SlashCommandNamedArgument( |
| 785 | 'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER], false, | 811 | 'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER], false, |
| 786 | ), | 812 | ), |
| 787 | SlashCommandNamedArgument.fromProps({ | 813 | SlashCommandNamedArgument.fromProps({ |
| 788 | name: 'as', | 814 | name: 'as', |
| 789 | description: 'role of the output prompt', | 815 | description: 'role of the output prompt', |
| 790 | typeList: [ARGUMENT_TYPE.STRING], | 816 | typeList: [ARGUMENT_TYPE.STRING], |
| 791 | enumList: [ | 817 | enumList: [ |
| 792 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.assistant), | 818 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.assistant), |
| 793 | new SlashCommandEnumValue('char', null, enumTypes.enum, enumIcons.character), | 819 | new SlashCommandEnumValue('char', null, enumTypes.enum, enumIcons.character), |
| 794 | ], | 820 | ], |
| 795 | }), | 821 | }), |
| 796 | ], | 822 | ], |
| 797 | unnamedArgumentList: [ | 823 | unnamedArgumentList: [ |
| 798 | new SlashCommandArgument( | 824 | new SlashCommandArgument( |
| 799 | 'prompt', [ARGUMENT_TYPE.STRING], true, | 825 | 'prompt', [ARGUMENT_TYPE.STRING], true, |
| 800 | ), | 826 | ), |
| 801 | ], | 827 | ], |
| 802 | helpString: ` | 828 | helpString: ` |
| 803 | <div> | 829 | <div> |
| 804 | Generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating and allowing to configure the in-prompt name for instruct mode (default = "System"). | 830 | Generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating and allowing to configure the in-prompt name for instruct mode (default = "System"). |
| 805 | </div> | 831 | </div> |
| @@ -807,43 +833,43 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 807 | "as" argument controls the role of the output prompt: system (default) or char. If "length" argument is provided as a number in tokens, allows to temporarily override an API response length. | 833 | "as" argument controls the role of the output prompt: system (default) or char. If "length" argument is provided as a number in tokens, allows to temporarily override an API response length. |
| 808 | </div> | 834 | </div> |
| 809 | `, | 835 | `, |
| 810 | })); | 836 | })); |
| 811 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 837 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 812 | name: 'genraw', | 838 | name: 'genraw', |
| 813 | callback: generateRawCallback, | 839 | callback: generateRawCallback, |
| 814 | returns: 'generated text', | 840 | returns: 'generated text', |
| 815 | namedArgumentList: [ | 841 | namedArgumentList: [ |
| 816 | new SlashCommandNamedArgument( | 842 | new SlashCommandNamedArgument( |
| 817 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), | 843 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), |
| 818 | ), | 844 | ), |
| 819 | new SlashCommandNamedArgument( | 845 | new SlashCommandNamedArgument( |
| 820 | 'instruct', 'use instruct mode', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(), | 846 | 'instruct', 'use instruct mode', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(), |
| 821 | ), | 847 | ), |
| 822 | new SlashCommandNamedArgument( | 848 | new SlashCommandNamedArgument( |
| 823 | 'stop', 'one-time custom stop strings', [ARGUMENT_TYPE.LIST], false, | 849 | 'stop', 'one-time custom stop strings', [ARGUMENT_TYPE.LIST], false, |
| 824 | ), | 850 | ), |
| 825 | SlashCommandNamedArgument.fromProps({ | 851 | SlashCommandNamedArgument.fromProps({ |
| 826 | name: 'as', | 852 | name: 'as', |
| 827 | description: 'role of the output prompt', | 853 | description: 'role of the output prompt', |
| 828 | typeList: [ARGUMENT_TYPE.STRING], | 854 | typeList: [ARGUMENT_TYPE.STRING], |
| 829 | enumList: [ | 855 | enumList: [ |
| 830 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.assistant), | 856 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.assistant), |
| 831 | new SlashCommandEnumValue('char', null, enumTypes.enum, enumIcons.character), | 857 | new SlashCommandEnumValue('char', null, enumTypes.enum, enumIcons.character), |
| 832 | ], | 858 | ], |
| 833 | }), | 859 | }), |
| 834 | new SlashCommandNamedArgument( | 860 | new SlashCommandNamedArgument( |
| 835 | 'system', 'system prompt at the start', [ARGUMENT_TYPE.STRING], false, | 861 | 'system', 'system prompt at the start', [ARGUMENT_TYPE.STRING], false, |
| 836 | ), | 862 | ), |
| 837 | new SlashCommandNamedArgument( | 863 | new SlashCommandNamedArgument( |
| 838 | 'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER], false, | 864 | 'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER], false, |
| 839 | ), | 865 | ), |
| 840 | ], | 866 | ], |
| 841 | unnamedArgumentList: [ | 867 | unnamedArgumentList: [ |
| 842 | new SlashCommandArgument( | 868 | new SlashCommandArgument( |
| 843 | 'prompt', [ARGUMENT_TYPE.STRING], true, | 869 | 'prompt', [ARGUMENT_TYPE.STRING], true, |
| 844 | ), | 870 | ), |
| 845 | ], | 871 | ], |
| 846 | helpString: ` | 872 | helpString: ` |
| 847 | <div> | 873 | <div> |
| 848 | Generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating. Does not include chat history or character card. | 874 | Generates text using the provided prompt and passes it to the next command through the pipe, optionally locking user input while generating. Does not include chat history or character card. |
| 849 | </div> | 875 | </div> |
| @@ -860,55 +886,55 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 860 | If "length" argument is provided as a number in tokens, allows to temporarily override an API response length. | 886 | If "length" argument is provided as a number in tokens, allows to temporarily override an API response length. |
| 861 | </div> | 887 | </div> |
| 862 | `, | 888 | `, |
| 863 | })); | 889 | })); |
| 864 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 890 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 865 | name: 'addswipe', | 891 | name: 'addswipe', |
| 866 | callback: addSwipeCallback, | 892 | callback: addSwipeCallback, |
| 867 | aliases: ['swipeadd'], | 893 | aliases: ['swipeadd'], |
| 868 | unnamedArgumentList: [ | 894 | unnamedArgumentList: [ |
| 869 | new SlashCommandArgument( | 895 | new SlashCommandArgument( |
| 870 | 'text', [ARGUMENT_TYPE.STRING], true, | 896 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 871 | ), | 897 | ), |
| 872 | ], | 898 | ], |
| 873 | helpString: 'Adds a swipe to the last chat message.', | 899 | helpString: 'Adds a swipe to the last chat message.', |
| 874 | })); | 900 | })); |
| 875 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 901 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 876 | name: 'abort', | 902 | name: 'abort', |
| 877 | callback: abortCallback, | 903 | callback: abortCallback, |
| 878 | namedArgumentList: [ | 904 | namedArgumentList: [ |
| 879 | SlashCommandNamedArgument.fromProps({ | 905 | SlashCommandNamedArgument.fromProps({ |
| 880 | name: 'quiet', | 906 | name: 'quiet', |
| 881 | description: 'Whether to suppress the toast message notifying about the /abort call.', | 907 | description: 'Whether to suppress the toast message notifying about the /abort call.', |
| 882 | typeList: [ARGUMENT_TYPE.BOOLEAN], | 908 | typeList: [ARGUMENT_TYPE.BOOLEAN], |
| 883 | defaultValue: 'true', | 909 | defaultValue: 'true', |
| 884 | }), | 910 | }), |
| 885 | ], | 911 | ], |
| 886 | unnamedArgumentList: [ | 912 | unnamedArgumentList: [ |
| 887 | SlashCommandArgument.fromProps({ | 913 | SlashCommandArgument.fromProps({ |
| 888 | description: 'The reason for aborting command execution. Shown when quiet=false', | 914 | description: 'The reason for aborting command execution. Shown when quiet=false', |
| 889 | typeList: [ARGUMENT_TYPE.STRING], | 915 | typeList: [ARGUMENT_TYPE.STRING], |
| 890 | }), | 916 | }), |
| 891 | ], | 917 | ], |
| 892 | helpString: 'Aborts the slash command batch execution.', | 918 | helpString: 'Aborts the slash command batch execution.', |
| 893 | })); | 919 | })); |
| 894 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 920 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 895 | name: 'fuzzy', | 921 | name: 'fuzzy', |
| 896 | callback: fuzzyCallback, | 922 | callback: fuzzyCallback, |
| 897 | returns: 'first matching item', | 923 | returns: 'first matching item', |
| 898 | namedArgumentList: [ | 924 | namedArgumentList: [ |
| 899 | new SlashCommandNamedArgument( | 925 | new SlashCommandNamedArgument( |
| 900 | 'list', 'list of items to match against', [ARGUMENT_TYPE.LIST], true, | 926 | 'list', 'list of items to match against', [ARGUMENT_TYPE.LIST], true, |
| 901 | ), | 927 | ), |
| 902 | new SlashCommandNamedArgument( | 928 | new SlashCommandNamedArgument( |
| 903 | 'threshold', 'fuzzy match threshold (0.0 to 1.0)', [ARGUMENT_TYPE.NUMBER], false, false, '0.4', | 929 | 'threshold', 'fuzzy match threshold (0.0 to 1.0)', [ARGUMENT_TYPE.NUMBER], false, false, '0.4', |
| 904 | ), | 930 | ), |
| 905 | ], | 931 | ], |
| 906 | unnamedArgumentList: [ | 932 | unnamedArgumentList: [ |
| 907 | new SlashCommandArgument( | 933 | new SlashCommandArgument( |
| 908 | 'text to search', [ARGUMENT_TYPE.STRING], true, | 934 | 'text to search', [ARGUMENT_TYPE.STRING], true, |
| 909 | ), | 935 | ), |
| 910 | ], | 936 | ], |
| 911 | helpString: ` | 937 | helpString: ` |
| 912 | <div> | 938 | <div> |
| 913 | Performs a fuzzy match of each item in the <code>list</code> against the <code>text to search</code>. | 939 | Performs a fuzzy match of each item in the <code>list</code> against the <code>text to search</code>. |
| 914 | If any item matches, then its name is returned. If no item matches the text, no value is returned. | 940 | If any item matches, then its name is returned. If no item matches the text, no value is returned. |
| @@ -930,23 +956,23 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 930 | </ul> | 956 | </ul> |
| 931 | </div> | 957 | </div> |
| 932 | `, | 958 | `, |
| 933 | })); | 959 | })); |
| 934 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 960 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 935 | name: 'pass', | 961 | name: 'pass', |
| 936 | callback: (_, arg) => { | 962 | callback: (_, arg) => { |
| 937 | // We do not support arrays of closures. Arrays of strings will be send as JSON | 963 | // We do not support arrays of closures. Arrays of strings will be send as JSON |
| 938 | if (Array.isArray(arg) && arg.some(x => x instanceof SlashCommandClosure)) throw new Error('Command /pass does not support multiple closures'); | 964 | if (Array.isArray(arg) && arg.some(x => x instanceof SlashCommandClosure)) throw new Error('Command /pass does not support multiple closures'); |
| 939 | if (Array.isArray(arg)) return JSON.stringify(arg); | 965 | if (Array.isArray(arg)) return JSON.stringify(arg); |
| 940 | return arg; | 966 | return arg; |
| 941 | }, | 967 | }, |
| 942 | returns: 'the provided value', | 968 | returns: 'the provided value', |
| 943 | unnamedArgumentList: [ | 969 | unnamedArgumentList: [ |
| 944 | new SlashCommandArgument( | 970 | new SlashCommandArgument( |
| 945 | 'text', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.BOOLEAN, ARGUMENT_TYPE.LIST, ARGUMENT_TYPE.DICTIONARY, ARGUMENT_TYPE.CLOSURE], true, | 971 | 'text', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.BOOLEAN, ARGUMENT_TYPE.LIST, ARGUMENT_TYPE.DICTIONARY, ARGUMENT_TYPE.CLOSURE], true, |
| 946 | ), | 972 | ), |
| 947 | ], | 973 | ], |
| 948 | aliases: ['return'], | 974 | aliases: ['return'], |
| 949 | helpString: ` | 975 | helpString: ` |
| 950 | <div> | 976 | <div> |
| 951 | <pre><span class="monospace">/pass (text)</span> – passes the text to the next command through the pipe.</pre> | 977 | <pre><span class="monospace">/pass (text)</span> – passes the text to the next command through the pipe.</pre> |
| 952 | </div> | 978 | </div> |
| @@ -957,17 +983,17 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 957 | </ul> | 983 | </ul> |
| 958 | </div> | 984 | </div> |
| 959 | `, | 985 | `, |
| 960 | })); | 986 | })); |
| 961 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 987 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 962 | name: 'delay', | 988 | name: 'delay', |
| 963 | callback: delayCallback, | 989 | callback: delayCallback, |
| 964 | aliases: ['wait', 'sleep'], | 990 | aliases: ['wait', 'sleep'], |
| 965 | unnamedArgumentList: [ | 991 | unnamedArgumentList: [ |
| 966 | new SlashCommandArgument( | 992 | new SlashCommandArgument( |
| 967 | 'milliseconds', [ARGUMENT_TYPE.NUMBER], true, | 993 | 'milliseconds', [ARGUMENT_TYPE.NUMBER], true, |
| 968 | ), | 994 | ), |
| 969 | ], | 995 | ], |
| 970 | helpString: ` | 996 | helpString: ` |
| 971 | <div> | 997 | <div> |
| 972 | Delays the next command in the pipe by the specified number of milliseconds. | 998 | Delays the next command in the pipe by the specified number of milliseconds. |
| 973 | </div> | 999 | </div> |
| @@ -980,101 +1006,101 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 980 | </ul> | 1006 | </ul> |
| 981 | </div> | 1007 | </div> |
| 982 | `, | 1008 | `, |
| 983 | })); | 1009 | })); |
| 984 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1010 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 985 | name: 'input', | 1011 | name: 'input', |
| 986 | aliases: ['prompt'], | 1012 | aliases: ['prompt'], |
| 987 | callback: inputCallback, | 1013 | callback: inputCallback, |
| 988 | returns: 'user input', | 1014 | returns: 'user input', |
| 989 | namedArgumentList: [ | 1015 | namedArgumentList: [ |
| 990 | new SlashCommandNamedArgument( | 1016 | new SlashCommandNamedArgument( |
| 991 | 'default', 'default value of the input field', [ARGUMENT_TYPE.STRING], false, false, '"string"', | 1017 | 'default', 'default value of the input field', [ARGUMENT_TYPE.STRING], false, false, '"string"', |
| 992 | ), | 1018 | ), |
| 993 | new SlashCommandNamedArgument( | 1019 | new SlashCommandNamedArgument( |
| 994 | 'large', 'show large input field', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), | 1020 | 'large', 'show large input field', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), |
| 995 | ), | 1021 | ), |
| 996 | new SlashCommandNamedArgument( | 1022 | new SlashCommandNamedArgument( |
| 997 | 'wide', 'show wide input field', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), | 1023 | 'wide', 'show wide input field', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), |
| 998 | ), | 1024 | ), |
| 999 | new SlashCommandNamedArgument( | 1025 | new SlashCommandNamedArgument( |
| 1000 | 'okButton', 'text for the ok button', [ARGUMENT_TYPE.STRING], false, | 1026 | 'okButton', 'text for the ok button', [ARGUMENT_TYPE.STRING], false, |
| 1001 | ), | 1027 | ), |
| 1002 | new SlashCommandNamedArgument( | 1028 | new SlashCommandNamedArgument( |
| 1003 | 'rows', 'number of rows for the input field', [ARGUMENT_TYPE.NUMBER], false, | 1029 | 'rows', 'number of rows for the input field', [ARGUMENT_TYPE.NUMBER], false, |
| 1004 | ), | 1030 | ), |
| 1005 | ], | 1031 | ], |
| 1006 | unnamedArgumentList: [ | 1032 | unnamedArgumentList: [ |
| 1007 | new SlashCommandArgument( | 1033 | new SlashCommandArgument( |
| 1008 | 'text to display', [ARGUMENT_TYPE.STRING], false, | 1034 | 'text to display', [ARGUMENT_TYPE.STRING], false, |
| 1009 | ), | 1035 | ), |
| 1010 | ], | 1036 | ], |
| 1011 | helpString: ` | 1037 | helpString: ` |
| 1012 | <div> | 1038 | <div> |
| 1013 | Shows a popup with the provided text and an input field. | 1039 | Shows a popup with the provided text and an input field. |
| 1014 | The <code>default</code> argument is the default value of the input field, and the text argument is the text to display. | 1040 | The <code>default</code> argument is the default value of the input field, and the text argument is the text to display. |
| 1015 | </div> | 1041 | </div> |
| 1016 | `, | 1042 | `, |
| 1017 | })); | 1043 | })); |
| 1018 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1044 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1019 | name: 'run', | 1045 | name: 'run', |
| 1020 | aliases: ['call', 'exec'], | 1046 | aliases: ['call', 'exec'], |
| 1021 | callback: runCallback, | 1047 | callback: runCallback, |
| 1022 | returns: 'result of the executed closure of QR', | 1048 | returns: 'result of the executed closure of QR', |
| 1023 | namedArgumentList: [ | 1049 | namedArgumentList: [ |
| 1024 | new SlashCommandNamedArgument( | 1050 | new SlashCommandNamedArgument( |
| 1025 | 'args', 'named arguments', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.BOOLEAN, ARGUMENT_TYPE.LIST, ARGUMENT_TYPE.DICTIONARY], false, true, | 1051 | 'args', 'named arguments', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.BOOLEAN, ARGUMENT_TYPE.LIST, ARGUMENT_TYPE.DICTIONARY], false, true, |
| 1026 | ), | 1052 | ), |
| 1027 | ], | 1053 | ], |
| 1028 | unnamedArgumentList: [ | 1054 | unnamedArgumentList: [ |
| 1029 | SlashCommandArgument.fromProps({ | 1055 | SlashCommandArgument.fromProps({ |
| 1030 | description: 'scoped variable or qr label', | 1056 | description: 'scoped variable or qr label', |
| 1031 | typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING], | 1057 | typeList: [ARGUMENT_TYPE.VARIABLE_NAME, ARGUMENT_TYPE.STRING], |
| 1032 | isRequired: true, | 1058 | isRequired: true, |
| 1033 | enumProvider: () => [ | 1059 | enumProvider: () => [ |
| 1034 | ...commonEnumProviders.variables('scope')(), | 1060 | ...commonEnumProviders.variables('scope')(), |
| 1035 | ...(typeof window['qrEnumProviderExecutables'] === 'function') ? window['qrEnumProviderExecutables']() : [], | 1061 | ...(typeof window['qrEnumProviderExecutables'] === 'function') ? window['qrEnumProviderExecutables']() : [], |
| 1036 | ], | 1062 | ], |
| 1037 | }), | 1063 | }), |
| 1038 | ], | 1064 | ], |
| 1039 | helpString: ` | 1065 | helpString: ` |
| 1040 | <div> | 1066 | <div> |
| 1041 | Runs a closure from a scoped variable, or a Quick Reply with the specified name from a currently active preset or from another preset. | 1067 | Runs a closure from a scoped variable, or a Quick Reply with the specified name from a currently active preset or from another preset. |
| 1042 | Named arguments can be referenced in a QR with <code>{{arg::key}}</code>. | 1068 | Named arguments can be referenced in a QR with <code>{{arg::key}}</code>. |
| 1043 | </div> | 1069 | </div> |
| 1044 | `, | 1070 | `, |
| 1045 | })); | 1071 | })); |
| 1046 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1072 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1047 | name: 'messages', | 1073 | name: 'messages', |
| 1048 | callback: getMessagesCallback, | 1074 | callback: getMessagesCallback, |
| 1049 | aliases: ['message'], | 1075 | aliases: ['message'], |
| 1050 | namedArgumentList: [ | 1076 | namedArgumentList: [ |
| 1051 | new SlashCommandNamedArgument( | 1077 | new SlashCommandNamedArgument( |
| 1052 | 'names', 'show message author names', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), | 1078 | 'names', 'show message author names', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(), |
| 1053 | ), | 1079 | ), |
| 1054 | new SlashCommandNamedArgument( | 1080 | new SlashCommandNamedArgument( |
| 1055 | 'hidden', 'include hidden messages', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(), | 1081 | 'hidden', 'include hidden messages', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(), |
| 1056 | ), | 1082 | ), |
| 1057 | SlashCommandNamedArgument.fromProps({ | 1083 | SlashCommandNamedArgument.fromProps({ |
| 1058 | name: 'role', | 1084 | name: 'role', |
| 1059 | description: 'filter messages by role', | 1085 | description: 'filter messages by role', |
| 1060 | typeList: [ARGUMENT_TYPE.STRING], | 1086 | typeList: [ARGUMENT_TYPE.STRING], |
| 1061 | enumList: [ | 1087 | enumList: [ |
| 1062 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.system), | 1088 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.system), |
| 1063 | new SlashCommandEnumValue('assistant', null, enumTypes.enum, enumIcons.assistant), | 1089 | new SlashCommandEnumValue('assistant', null, enumTypes.enum, enumIcons.assistant), |
| 1064 | new SlashCommandEnumValue('user', null, enumTypes.enum, enumIcons.user), | 1090 | new SlashCommandEnumValue('user', null, enumTypes.enum, enumIcons.user), |
| 1065 | ], | 1091 | ], |
| 1066 | }), | 1092 | }), |
| 1067 | ], | 1093 | ], |
| 1068 | unnamedArgumentList: [ | 1094 | unnamedArgumentList: [ |
| 1069 | SlashCommandArgument.fromProps({ | 1095 | SlashCommandArgument.fromProps({ |
| 1070 | description: 'message index (starts with 0) or range', | 1096 | description: 'message index (starts with 0) or range', |
| 1071 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], | 1097 | typeList: [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.RANGE], |
| 1072 | isRequired: true, | 1098 | isRequired: true, |
| 1073 | enumProvider: commonEnumProviders.messages(), | 1099 | enumProvider: commonEnumProviders.messages(), |
| 1074 | }), | 1100 | }), |
| 1075 | ], | 1101 | ], |
| 1076 | returns: 'the specified message or range of messages as a string', | 1102 | returns: 'the specified message or range of messages as a string', |
| 1077 | helpString: ` | 1103 | helpString: ` |
| 1078 | <div> | 1104 | <div> |
| 1079 | Returns the specified message or range of messages as a string. | 1105 | Returns the specified message or range of messages as a string. |
| 1080 | </div> | 1106 | </div> |
| @@ -1098,16 +1124,16 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1098 | </ul> | 1124 | </ul> |
| 1099 | </div> | 1125 | </div> |
| 1100 | `, | 1126 | `, |
| 1101 | })); | 1127 | })); |
| 1102 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1128 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1103 | name: 'setinput', | 1129 | name: 'setinput', |
| 1104 | callback: setInputCallback, | 1130 | callback: setInputCallback, |
| 1105 | unnamedArgumentList: [ | 1131 | unnamedArgumentList: [ |
| 1106 | new SlashCommandArgument( | 1132 | new SlashCommandArgument( |
| 1107 | 'text', [ARGUMENT_TYPE.STRING], true, | 1133 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1108 | ), | 1134 | ), |
| 1109 | ], | 1135 | ], |
| 1110 | helpString: ` | 1136 | helpString: ` |
| 1111 | <div> | 1137 | <div> |
| 1112 | Sets the user input to the specified text and passes it to the next command through the pipe. | 1138 | Sets the user input to the specified text and passes it to the next command through the pipe. |
| 1113 | </div> | 1139 | </div> |
| @@ -1120,28 +1146,28 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1120 | </ul> | 1146 | </ul> |
| 1121 | </div> | 1147 | </div> |
| 1122 | `, | 1148 | `, |
| 1123 | })); | 1149 | })); |
| 1124 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1150 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1125 | name: 'popup', | 1151 | name: 'popup', |
| 1126 | callback: popupCallback, | 1152 | callback: popupCallback, |
| 1127 | returns: 'popup text', | 1153 | returns: 'popup text', |
| 1128 | namedArgumentList: [ | 1154 | namedArgumentList: [ |
| 1129 | new SlashCommandNamedArgument( | 1155 | new SlashCommandNamedArgument( |
| 1130 | 'large', 'show large popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), | 1156 | 'large', 'show large popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), |
| 1131 | ), | 1157 | ), |
| 1132 | new SlashCommandNamedArgument( | 1158 | new SlashCommandNamedArgument( |
| 1133 | 'wide', 'show wide popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), | 1159 | 'wide', 'show wide popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), |
| 1134 | ), | 1160 | ), |
| 1135 | new SlashCommandNamedArgument( | 1161 | new SlashCommandNamedArgument( |
| 1136 | 'okButton', 'text for the OK button', [ARGUMENT_TYPE.STRING], false, | 1162 | 'okButton', 'text for the OK button', [ARGUMENT_TYPE.STRING], false, |
| 1137 | ), | 1163 | ), |
| 1138 | ], | 1164 | ], |
| 1139 | unnamedArgumentList: [ | 1165 | unnamedArgumentList: [ |
| 1140 | new SlashCommandArgument( | 1166 | new SlashCommandArgument( |
| 1141 | 'text', [ARGUMENT_TYPE.STRING], true, | 1167 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1142 | ), | 1168 | ), |
| 1143 | ], | 1169 | ], |
| 1144 | helpString: ` | 1170 | helpString: ` |
| 1145 | <div> | 1171 | <div> |
| 1146 | Shows a blocking popup with the specified text and buttons. | 1172 | Shows a blocking popup with the specified text and buttons. |
| 1147 | Returns the popup text. | 1173 | Returns the popup text. |
| @@ -1155,22 +1181,22 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1155 | </ul> | 1181 | </ul> |
| 1156 | </div> | 1182 | </div> |
| 1157 | `, | 1183 | `, |
| 1158 | })); | 1184 | })); |
| 1159 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1185 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1160 | name: 'buttons', | 1186 | name: 'buttons', |
| 1161 | callback: buttonsCallback, | 1187 | callback: buttonsCallback, |
| 1162 | returns: 'clicked button label', | 1188 | returns: 'clicked button label', |
| 1163 | namedArgumentList: [ | 1189 | namedArgumentList: [ |
| 1164 | new SlashCommandNamedArgument( | 1190 | new SlashCommandNamedArgument( |
| 1165 | 'labels', 'button labels', [ARGUMENT_TYPE.LIST], true, | 1191 | 'labels', 'button labels', [ARGUMENT_TYPE.LIST], true, |
| 1166 | ), | 1192 | ), |
| 1167 | ], | 1193 | ], |
| 1168 | unnamedArgumentList: [ | 1194 | unnamedArgumentList: [ |
| 1169 | new SlashCommandArgument( | 1195 | new SlashCommandArgument( |
| 1170 | 'text', [ARGUMENT_TYPE.STRING], true, | 1196 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1171 | ), | 1197 | ), |
| 1172 | ], | 1198 | ], |
| 1173 | helpString: ` | 1199 | helpString: ` |
| 1174 | <div> | 1200 | <div> |
| 1175 | Shows a blocking popup with the specified text and buttons. | 1201 | Shows a blocking popup with the specified text and buttons. |
| 1176 | Returns the clicked button label into the pipe or empty string if canceled. | 1202 | Returns the clicked button label into the pipe or empty string if canceled. |
| @@ -1184,32 +1210,32 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1184 | </ul> | 1210 | </ul> |
| 1185 | </div> | 1211 | </div> |
| 1186 | `, | 1212 | `, |
| 1187 | })); | 1213 | })); |
| 1188 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1214 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1189 | name: 'trimtokens', | 1215 | name: 'trimtokens', |
| 1190 | callback: trimTokensCallback, | 1216 | callback: trimTokensCallback, |
| 1191 | returns: 'trimmed text', | 1217 | returns: 'trimmed text', |
| 1192 | namedArgumentList: [ | 1218 | namedArgumentList: [ |
| 1193 | new SlashCommandNamedArgument( | 1219 | new SlashCommandNamedArgument( |
| 1194 | 'limit', 'number of tokens to keep', [ARGUMENT_TYPE.NUMBER], true, | 1220 | 'limit', 'number of tokens to keep', [ARGUMENT_TYPE.NUMBER], true, |
| 1195 | ), | 1221 | ), |
| 1196 | SlashCommandNamedArgument.fromProps({ | 1222 | SlashCommandNamedArgument.fromProps({ |
| 1197 | name: 'direction', | 1223 | name: 'direction', |
| 1198 | description: 'trim direction', | 1224 | description: 'trim direction', |
| 1199 | typeList: [ARGUMENT_TYPE.STRING], | 1225 | typeList: [ARGUMENT_TYPE.STRING], |
| 1200 | isRequired: true, | 1226 | isRequired: true, |
| 1201 | enumList: [ | 1227 | enumList: [ |
| 1202 | new SlashCommandEnumValue('start', null, enumTypes.enum, '⏪'), | 1228 | new SlashCommandEnumValue('start', null, enumTypes.enum, '⏪'), |
| 1203 | new SlashCommandEnumValue('end', null, enumTypes.enum, '⏩'), | 1229 | new SlashCommandEnumValue('end', null, enumTypes.enum, '⏩'), |
| 1204 | ], | 1230 | ], |
| 1205 | }), | 1231 | }), |
| 1206 | ], | 1232 | ], |
| 1207 | unnamedArgumentList: [ | 1233 | unnamedArgumentList: [ |
| 1208 | new SlashCommandArgument( | 1234 | new SlashCommandArgument( |
| 1209 | 'text', [ARGUMENT_TYPE.STRING], false, | 1235 | 'text', [ARGUMENT_TYPE.STRING], false, |
| 1210 | ), | 1236 | ), |
| 1211 | ], | 1237 | ], |
| 1212 | helpString: ` | 1238 | helpString: ` |
| 1213 | <div> | 1239 | <div> |
| 1214 | Trims the start or end of text to the specified number of tokens. | 1240 | Trims the start or end of text to the specified number of tokens. |
| 1215 | </div> | 1241 | </div> |
| @@ -1222,17 +1248,17 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1222 | </ul> | 1248 | </ul> |
| 1223 | </div> | 1249 | </div> |
| 1224 | `, | 1250 | `, |
| 1225 | })); | 1251 | })); |
| 1226 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1252 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1227 | name: 'trimstart', | 1253 | name: 'trimstart', |
| 1228 | callback: trimStartCallback, | 1254 | callback: trimStartCallback, |
| 1229 | returns: 'trimmed text', | 1255 | returns: 'trimmed text', |
| 1230 | unnamedArgumentList: [ | 1256 | unnamedArgumentList: [ |
| 1231 | new SlashCommandArgument( | 1257 | new SlashCommandArgument( |
| 1232 | 'text', [ARGUMENT_TYPE.STRING], true, | 1258 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1233 | ), | 1259 | ), |
| 1234 | ], | 1260 | ], |
| 1235 | helpString: ` | 1261 | helpString: ` |
| 1236 | <div> | 1262 | <div> |
| 1237 | Trims the text to the start of the first full sentence. | 1263 | Trims the text to the start of the first full sentence. |
| 1238 | </div> | 1264 | </div> |
| @@ -1245,148 +1271,149 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |||
| 1245 | </ul> | 1271 | </ul> |
| 1246 | </div> | 1272 | </div> |
| 1247 | `, | 1273 | `, |
| 1248 | })); | 1274 | })); |
| 1249 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1275 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1250 | name: 'trimend', | 1276 | name: 'trimend', |
| 1251 | callback: trimEndCallback, | 1277 | callback: trimEndCallback, |
| 1252 | returns: 'trimmed text', | 1278 | returns: 'trimmed text', |
| 1253 | unnamedArgumentList: [ | 1279 | unnamedArgumentList: [ |
| 1254 | new SlashCommandArgument( | 1280 | new SlashCommandArgument( |
| 1255 | 'text', [ARGUMENT_TYPE.STRING], true, | 1281 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1256 | ), | 1282 | ), |
| 1257 | ], | 1283 | ], |
| 1258 | helpString: 'Trims the text to the end of the last full sentence.', | 1284 | helpString: 'Trims the text to the end of the last full sentence.', |
| 1259 | })); | 1285 | })); |
| 1260 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1286 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1261 | name: 'inject', | 1287 | name: 'inject', |
| 1262 | callback: injectCallback, | 1288 | callback: injectCallback, |
| 1263 | namedArgumentList: [ | 1289 | namedArgumentList: [ |
| 1264 | SlashCommandNamedArgument.fromProps({ | 1290 | SlashCommandNamedArgument.fromProps({ |
| 1265 | name: 'id', | 1291 | name: 'id', |
| 1266 | description: 'injection ID or variable name pointing to ID', | 1292 | description: 'injection ID or variable name pointing to ID', |
| 1267 | typeList: [ARGUMENT_TYPE.STRING], | 1293 | typeList: [ARGUMENT_TYPE.STRING], |
| 1268 | isRequired: true, | 1294 | isRequired: true, |
| 1269 | enumProvider: commonEnumProviders.injects, | 1295 | enumProvider: commonEnumProviders.injects, |
| 1270 | }), | 1296 | }), |
| 1271 | new SlashCommandNamedArgument( | 1297 | new SlashCommandNamedArgument( |
| 1272 | 'position', 'injection position', [ARGUMENT_TYPE.STRING], false, false, 'after', ['before', 'after', 'chat'], | 1298 | 'position', 'injection position', [ARGUMENT_TYPE.STRING], false, false, 'after', ['before', 'after', 'chat'], |
| 1273 | ), | 1299 | ), |
| 1274 | new SlashCommandNamedArgument( | 1300 | new SlashCommandNamedArgument( |
| 1275 | 'depth', 'injection depth', [ARGUMENT_TYPE.NUMBER], false, false, '4', | 1301 | 'depth', 'injection depth', [ARGUMENT_TYPE.NUMBER], false, false, '4', |
| 1276 | ), | 1302 | ), |
| 1277 | new SlashCommandNamedArgument( | 1303 | new SlashCommandNamedArgument( |
| 1278 | 'scan', 'include injection content into World Info scans', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', | 1304 | 'scan', 'include injection content into World Info scans', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', |
| 1279 | ), | 1305 | ), |
| 1280 | SlashCommandNamedArgument.fromProps({ | 1306 | SlashCommandNamedArgument.fromProps({ |
| 1281 | name: 'role', | 1307 | name: 'role', |
| 1282 | description: 'role for in-chat injections', | 1308 | description: 'role for in-chat injections', |
| 1283 | typeList: [ARGUMENT_TYPE.STRING], | 1309 | typeList: [ARGUMENT_TYPE.STRING], |
| 1284 | isRequired: false, | 1310 | isRequired: false, |
| 1285 | enumList: [ | 1311 | enumList: [ |
| 1286 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.system), | 1312 | new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.system), |
| 1287 | new SlashCommandEnumValue('assistant', null, enumTypes.enum, enumIcons.assistant), | 1313 | new SlashCommandEnumValue('assistant', null, enumTypes.enum, enumIcons.assistant), |
| 1288 | new SlashCommandEnumValue('user', null, enumTypes.enum, enumIcons.user), | 1314 | new SlashCommandEnumValue('user', null, enumTypes.enum, enumIcons.user), |
| 1289 | ], | 1315 | ], |
| 1290 | }), | 1316 | }), |
| 1291 | new SlashCommandNamedArgument( | 1317 | new SlashCommandNamedArgument( |
| 1292 | 'ephemeral', 'remove injection after generation', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', | 1318 | 'ephemeral', 'remove injection after generation', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false', |
| 1293 | ), | 1319 | ), |
| 1294 | ], | 1320 | ], |
| 1295 | unnamedArgumentList: [ | 1321 | unnamedArgumentList: [ |
| 1296 | new SlashCommandArgument( | 1322 | new SlashCommandArgument( |
| 1297 | 'text', [ARGUMENT_TYPE.STRING], false, | 1323 | 'text', [ARGUMENT_TYPE.STRING], false, |
| 1298 | ), | 1324 | ), |
| 1299 | ], | 1325 | ], |
| 1300 | helpString: 'Injects a text into the LLM prompt for the current chat. Requires a unique injection ID. Positions: "before" main prompt, "after" main prompt, in-"chat" (default: after). Depth: injection depth for the prompt (default: 4). Role: role for in-chat injections (default: system). Scan: include injection content into World Info scans (default: false).', | 1326 | helpString: 'Injects a text into the LLM prompt for the current chat. Requires a unique injection ID. Positions: "before" main prompt, "after" main prompt, in-"chat" (default: after). Depth: injection depth for the prompt (default: 4). Role: role for in-chat injections (default: system). Scan: include injection content into World Info scans (default: false).', |
| 1301 | })); | 1327 | })); |
| 1302 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1328 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1303 | name: 'listinjects', | 1329 | name: 'listinjects', |
| 1304 | callback: listInjectsCallback, | 1330 | callback: listInjectsCallback, |
| 1305 | helpString: 'Lists all script injections for the current chat.', | 1331 | helpString: 'Lists all script injections for the current chat.', |
| 1306 | })); | 1332 | })); |
| 1307 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1333 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1308 | name: 'flushinject', | 1334 | name: 'flushinject', |
| 1309 | aliases: ['flushinjects'], | 1335 | aliases: ['flushinjects'], |
| 1310 | unnamedArgumentList: [ | 1336 | unnamedArgumentList: [ |
| 1311 | SlashCommandArgument.fromProps({ | 1337 | SlashCommandArgument.fromProps({ |
| 1312 | description: 'injection ID or a variable name pointing to ID', | 1338 | description: 'injection ID or a variable name pointing to ID', |
| 1313 | typeList: [ARGUMENT_TYPE.STRING], | 1339 | typeList: [ARGUMENT_TYPE.STRING], |
| 1314 | defaultValue: '', | 1340 | defaultValue: '', |
| 1315 | enumProvider: commonEnumProviders.injects, | 1341 | enumProvider: commonEnumProviders.injects, |
| 1316 | }), | 1342 | }), |
| 1317 | ], | 1343 | ], |
| 1318 | callback: flushInjectsCallback, | 1344 | callback: flushInjectsCallback, |
| 1319 | helpString: 'Removes a script injection for the current chat. If no ID is provided, removes all script injections.', | 1345 | helpString: 'Removes a script injection for the current chat. If no ID is provided, removes all script injections.', |
| 1320 | })); | 1346 | })); |
| 1321 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1347 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1322 | name: 'tokens', | 1348 | name: 'tokens', |
| 1323 | callback: (_, text) => { | 1349 | callback: (_, text) => { |
| 1324 | if (text instanceof SlashCommandClosure || Array.isArray(text)) throw new Error('Unnamed argument cannot be a closure for command /tokens'); | 1350 | if (text instanceof SlashCommandClosure || Array.isArray(text)) throw new Error('Unnamed argument cannot be a closure for command /tokens'); |
| 1325 | return getTokenCountAsync(text).then(count => String(count)); | 1351 | return getTokenCountAsync(text).then(count => String(count)); |
| 1326 | }, | 1352 | }, |
| 1327 | returns: 'number of tokens', | 1353 | returns: 'number of tokens', |
| 1328 | unnamedArgumentList: [ | 1354 | unnamedArgumentList: [ |
| 1329 | new SlashCommandArgument( | 1355 | new SlashCommandArgument( |
| 1330 | 'text', [ARGUMENT_TYPE.STRING], true, | 1356 | 'text', [ARGUMENT_TYPE.STRING], true, |
| 1331 | ), | 1357 | ), |
| 1332 | ], | 1358 | ], |
| 1333 | helpString: 'Counts the number of tokens in the provided text.', | 1359 | helpString: 'Counts the number of tokens in the provided text.', |
| 1334 | })); | 1360 | })); |
| 1335 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1361 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1336 | name: 'model', | 1362 | name: 'model', |
| 1337 | callback: modelCallback, | 1363 | callback: modelCallback, |
| 1338 | returns: 'current model', | 1364 | returns: 'current model', |
| 1339 | unnamedArgumentList: [ | 1365 | unnamedArgumentList: [ |
| 1340 | SlashCommandArgument.fromProps({ | 1366 | SlashCommandArgument.fromProps({ |
| 1341 | description: 'model name', | 1367 | description: 'model name', |
| 1342 | typeList: [ARGUMENT_TYPE.STRING], | 1368 | typeList: [ARGUMENT_TYPE.STRING], |
| 1343 | enumProvider: () => getModelOptions()?.options.map(option => new SlashCommandEnumValue(option.value, option.value !== option.text ? option.text : null)), | 1369 | enumProvider: () => getModelOptions()?.options.map(option => new SlashCommandEnumValue(option.value, option.value !== option.text ? option.text : null)), |
| 1344 | }), | 1370 | }), |
| 1345 | ], | 1371 | ], |
| 1346 | helpString: 'Sets the model for the current API. Gets the current model name if no argument is provided.', | 1372 | helpString: 'Sets the model for the current API. Gets the current model name if no argument is provided.', |
| 1347 | })); | 1373 | })); |
| 1348 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1374 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1349 | name: 'setpromptentry', | 1375 | name: 'setpromptentry', |
| 1350 | aliases: ['setpromptentries'], | 1376 | aliases: ['setpromptentries'], |
| 1351 | callback: setPromptEntryCallback, | 1377 | callback: setPromptEntryCallback, |
| 1352 | namedArgumentList: [ | 1378 | namedArgumentList: [ |
| 1353 | SlashCommandNamedArgument.fromProps({ | 1379 | SlashCommandNamedArgument.fromProps({ |
| 1354 | name: 'identifier', | 1380 | name: 'identifier', |
| 1355 | description: 'Prompt entry identifier(s) to target', | 1381 | description: 'Prompt entry identifier(s) to target', |
| 1356 | typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], | 1382 | typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], |
| 1357 | acceptsMultiple: true, | 1383 | acceptsMultiple: true, |
| 1358 | enumProvider: () => { | 1384 | enumProvider: () => { |
| 1359 | const promptManager = setupChatCompletionPromptManager(oai_settings); | 1385 | const promptManager = setupChatCompletionPromptManager(oai_settings); |
| 1360 | const prompts = promptManager.serviceSettings.prompts; | 1386 | const prompts = promptManager.serviceSettings.prompts; |
| 1361 | return prompts.map(prompt => new SlashCommandEnumValue(prompt.identifier, prompt.name, enumTypes.enum)); | 1387 | return prompts.map(prompt => new SlashCommandEnumValue(prompt.identifier, prompt.name, enumTypes.enum)); |
| 1362 | }, | 1388 | }, |
| 1363 | }), | 1389 | }), |
| 1364 | SlashCommandNamedArgument.fromProps({ | 1390 | SlashCommandNamedArgument.fromProps({ |
| 1365 | name: 'name', | 1391 | name: 'name', |
| 1366 | description: 'Prompt entry name(s) to target', | 1392 | description: 'Prompt entry name(s) to target', |
| 1367 | typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], | 1393 | typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST], |
| 1368 | acceptsMultiple: true, | 1394 | acceptsMultiple: true, |
| 1369 | enumProvider: () => { | 1395 | enumProvider: () => { |
| 1370 | const promptManager = setupChatCompletionPromptManager(oai_settings); | 1396 | const promptManager = setupChatCompletionPromptManager(oai_settings); |
| 1371 | const prompts = promptManager.serviceSettings.prompts; | 1397 | const prompts = promptManager.serviceSettings.prompts; |
| 1372 | return prompts.map(prompt => new SlashCommandEnumValue(prompt.name, prompt.identifier, enumTypes.enum)); | 1398 | return prompts.map(prompt => new SlashCommandEnumValue(prompt.name, prompt.identifier, enumTypes.enum)); |
| 1373 | }, | 1399 | }, |
| 1374 | }), | 1400 | }), |
| 1375 | ], | 1401 | ], |
| 1376 | unnamedArgumentList: [ | 1402 | unnamedArgumentList: [ |
| 1377 | SlashCommandArgument.fromProps({ | 1403 | SlashCommandArgument.fromProps({ |
| 1378 | description: 'Set entry/entries on or off', | 1404 | description: 'Set entry/entries on or off', |
| 1379 | typeList: [ARGUMENT_TYPE.STRING], | 1405 | typeList: [ARGUMENT_TYPE.STRING], |
| 1380 | isRequired: true, | 1406 | isRequired: true, |
| 1381 | acceptsMultiple: false, | 1407 | acceptsMultiple: false, |
| 1382 | defaultValue: 'toggle', // unnamed arguments don't support default values yet | 1408 | defaultValue: 'toggle', // unnamed arguments don't support default values yet |
| 1383 | enumList: commonEnumProviders.boolean('onOffToggle')(), | 1409 | enumList: commonEnumProviders.boolean('onOffToggle')(), |
| 1384 | }), | 1410 | }), |
| 1385 | ], | 1411 | ], |
| 1386 | helpString: 'Sets the specified prompt manager entry/entries on or off.', | 1412 | helpString: 'Sets the specified prompt manager entry/entries on or off.', |
| 1387 | })); | 1413 | })); |
| 1388 | 1414 | ||
| 1389 | registerVariableCommands(); | 1415 | registerVariableCommands(); |
| 1416 | } | ||
| 1390 | 1417 | ||
| 1391 | const NARRATOR_NAME_KEY = 'narrator_name'; | 1418 | const NARRATOR_NAME_KEY = 'narrator_name'; |
| 1392 | const NARRATOR_NAME_DEFAULT = 'System'; | 1419 | const NARRATOR_NAME_DEFAULT = 'System'; |
| @@ -1938,32 +1965,67 @@ async function generateCallback(args, value) { | |||
| 1938 | } | 1965 | } |
| 1939 | } | 1966 | } |
| 1940 | 1967 | ||
| 1968 | /** | ||
| 1969 | * | ||
| 1970 | * @param {{title?: string, severity?: string, timeout?: string, extendedTimeout?: string, preventDuplicates?: string, awaitDismissal?: string}} args - named arguments from the slash command | ||
| 1971 | * @param {string} value - The string to echo (unnamed argument from the slash command) | ||
| 1972 | * @returns {Promise<string>} The text that was echoed | ||
| 1973 | */ | ||
| 1941 | async function echoCallback(args, value) { | 1974 | async function echoCallback(args, value) { |
| 1942 | // Note: We don't need to sanitize input, as toastr is set up by default to escape HTML via toastr options | 1975 | // Note: We don't need to sanitize input, as toastr is set up by default to escape HTML via toastr options |
| 1943 | if (value === '') { | 1976 | if (value === '') { |
| 1944 | console.warn('WARN: No argument provided for /echo command'); | 1977 | console.warn('WARN: No argument provided for /echo command'); |
| 1945 | return; | 1978 | return ''; |
| 1946 | } | 1979 | } |
| 1947 | const title = args?.title !== undefined && typeof args?.title === 'string' ? args.title : undefined; | 1980 | |
| 1948 | const severity = args?.severity !== undefined && typeof args?.severity === 'string' ? args.severity : 'info'; | 1981 | if (args.severity && !['error', 'warning', 'success', 'info'].includes(args.severity)) { |
| 1982 | toastr.warning(`Invalid severity provided for /echo command: ${args.severity}`); | ||
| 1983 | args.severity = null; | ||
| 1984 | } | ||
| 1985 | |||
| 1986 | const title = args.title ? args.title : undefined; | ||
| 1987 | const severity = args.severity ? args.severity : 'info'; | ||
| 1988 | |||
| 1989 | /** @type {ToastrOptions} */ | ||
| 1990 | const options = {}; | ||
| 1991 | if (args.timeout && !isNaN(parseInt(args.timeout))) options.timeOut = parseInt(args.timeout); | ||
| 1992 | if (args.extendedTimeout && !isNaN(parseInt(args.extendedTimeout))) options.extendedTimeOut = parseInt(args.extendedTimeout); | ||
| 1993 | if (isTrueBoolean(args.preventDuplicates)) options.preventDuplicates = true; | ||
| 1994 | |||
| 1995 | // Prepare possible await handling | ||
| 1996 | let awaitDismissal = isTrueBoolean(args.awaitDismissal); | ||
| 1997 | let resolveToastDismissal; | ||
| 1998 | |||
| 1999 | if (awaitDismissal) { | ||
| 2000 | options.onHidden = () => resolveToastDismissal(value); | ||
| 2001 | } | ||
| 2002 | |||
| 1949 | switch (severity) { | 2003 | switch (severity) { |
| 1950 | case 'error': | 2004 | case 'error': |
| 1951 | toastr.error(value, title); | 2005 | toastr.error(value, title, options); |
| 1952 | break; | 2006 | break; |
| 1953 | case 'warning': | 2007 | case 'warning': |
| 1954 | toastr.warning(value, title); | 2008 | toastr.warning(value, title, options); |
| 1955 | break; | 2009 | break; |
| 1956 | case 'success': | 2010 | case 'success': |
| 1957 | toastr.success(value, title); | 2011 | toastr.success(value, title, options); |
| 1958 | break; | 2012 | break; |
| 1959 | case 'info': | 2013 | case 'info': |
| 1960 | default: | 2014 | default: |
| 1961 | toastr.info(value, title); | 2015 | toastr.info(value, title, options); |
| 1962 | break; | 2016 | break; |
| 1963 | } | 2017 | } |
| 1964 | return value; | 2018 | |
| 2019 | if (awaitDismissal) { | ||
| 2020 | return new Promise((resolve) => { | ||
| 2021 | resolveToastDismissal = resolve; | ||
| 2022 | }); | ||
| 2023 | } else { | ||
| 2024 | return value; | ||
| 2025 | } | ||
| 1965 | } | 2026 | } |
| 1966 | 2027 | ||
| 2028 | |||
| 1967 | async function addSwipeCallback(_, arg) { | 2029 | async function addSwipeCallback(_, arg) { |
| 1968 | const lastMessage = chat[chat.length - 1]; | 2030 | const lastMessage = chat[chat.length - 1]; |
| 1969 | 2031 | ||
| @@ -2428,7 +2490,14 @@ async function sendUserMessageCallback(args, text) { | |||
| 2428 | text = text.trim(); | 2490 | text = text.trim(); |
| 2429 | const compact = isTrueBoolean(args?.compact); | 2491 | const compact = isTrueBoolean(args?.compact); |
| 2430 | const bias = extractMessageBias(text); | 2492 | const bias = extractMessageBias(text); |
| 2431 | const insertAt = Number(args?.at); | 2493 | |
| 2494 | let insertAt = Number(args?.at); | ||
| 2495 | |||
| 2496 | // Convert possible depth parameter to index | ||
| 2497 | if (!isNaN(insertAt) && (insertAt < 0 || insertAt === Number(-0))) { | ||
| 2498 | // Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7) | ||
| 2499 | insertAt = chat.length + insertAt; | ||
| 2500 | } | ||
| 2432 | 2501 | ||
| 2433 | if ('name' in args) { | 2502 | if ('name' in args) { |
| 2434 | const name = args.name || ''; | 2503 | const name = args.name || ''; |
| @@ -2737,7 +2806,13 @@ export async function sendMessageAs(args, text) { | |||
| 2737 | }, | 2806 | }, |
| 2738 | }]; | 2807 | }]; |
| 2739 | 2808 | ||
| 2740 | const insertAt = Number(args.at); | 2809 | let insertAt = Number(args.at); |
| 2810 | |||
| 2811 | // Convert possible depth parameter to index | ||
| 2812 | if (!isNaN(insertAt) && (insertAt < 0 || insertAt === Number(-0))) { | ||
| 2813 | // Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7) | ||
| 2814 | insertAt = chat.length + insertAt; | ||
| 2815 | } | ||
| 2741 | 2816 | ||
| 2742 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { | 2817 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { |
| 2743 | chat.splice(insertAt, 0, message); | 2818 | chat.splice(insertAt, 0, message); |
| @@ -2784,7 +2859,13 @@ export async function sendNarratorMessage(args, text) { | |||
| 2784 | }, | 2859 | }, |
| 2785 | }; | 2860 | }; |
| 2786 | 2861 | ||
| 2787 | const insertAt = Number(args.at); | 2862 | let insertAt = Number(args.at); |
| 2863 | |||
| 2864 | // Convert possible depth parameter to index | ||
| 2865 | if (!isNaN(insertAt) && (insertAt < 0 || insertAt === Number(-0))) { | ||
| 2866 | // Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7) | ||
| 2867 | insertAt = chat.length + insertAt; | ||
| 2868 | } | ||
| 2788 | 2869 | ||
| 2789 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { | 2870 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { |
| 2790 | chat.splice(insertAt, 0, message); | 2871 | chat.splice(insertAt, 0, message); |
| @@ -2866,7 +2947,13 @@ async function sendCommentMessage(args, text) { | |||
| 2866 | }, | 2947 | }, |
| 2867 | }; | 2948 | }; |
| 2868 | 2949 | ||
| 2869 | const insertAt = Number(args.at); | 2950 | let insertAt = Number(args.at); |
| 2951 | |||
| 2952 | // Convert possible depth parameter to index | ||
| 2953 | if (!isNaN(insertAt) && (insertAt < 0 || insertAt === Number(-0))) { | ||
| 2954 | // Negative value means going back from current chat length. (E.g.: 8 messages, Depth 1 means insert at index 7) | ||
| 2955 | insertAt = chat.length + insertAt; | ||
| 2956 | } | ||
| 2870 | 2957 | ||
| 2871 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { | 2958 | if (!isNaN(insertAt) && insertAt >= 0 && insertAt <= chat.length) { |
| 2872 | chat.splice(insertAt, 0, message); | 2959 | chat.splice(insertAt, 0, message); |
| @@ -59,7 +59,7 @@ export class SlashCommandArgument { | |||
| 59 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} enums | 59 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} enums |
| 60 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} enumProvider function that returns auto complete options | 60 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} enumProvider function that returns auto complete options |
| 61 | */ | 61 | */ |
| 62 | constructor(description, types, isRequired = false, acceptsMultiple = false, defaultValue = null, enums = [], enumProvider = null, forceEnum = true) { | 62 | constructor(description, types, isRequired = false, acceptsMultiple = false, defaultValue = null, enums = [], enumProvider = null, forceEnum = false) { |
| 63 | this.description = description; | 63 | this.description = description; |
| 64 | this.typeList = types ? Array.isArray(types) ? types : [types] : []; | 64 | this.typeList = types ? Array.isArray(types) ? types : [types] : []; |
| 65 | this.isRequired = isRequired ?? false; | 65 | this.isRequired = isRequired ?? false; |
| @@ -90,7 +90,7 @@ export class SlashCommandNamedArgument extends SlashCommandArgument { | |||
| 90 | * @param {string|SlashCommandClosure} [props.defaultValue=null] default value if no value is provided | 90 | * @param {string|SlashCommandClosure} [props.defaultValue=null] default value if no value is provided |
| 91 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} [props.enumList=[]] list of accepted values | 91 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} [props.enumList=[]] list of accepted values |
| 92 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} [props.enumProvider=null] function that returns auto complete options | 92 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} [props.enumProvider=null] function that returns auto complete options |
| 93 | * @param {boolean} [props.forceEnum=true] default: true - whether the input must match one of the enum values | 93 | * @param {boolean} [props.forceEnum=false] default: false - whether the input must match one of the enum values |
| 94 | */ | 94 | */ |
| 95 | static fromProps(props) { | 95 | static fromProps(props) { |
| 96 | return new SlashCommandNamedArgument( | 96 | return new SlashCommandNamedArgument( |
| @@ -103,7 +103,7 @@ export class SlashCommandNamedArgument extends SlashCommandArgument { | |||
| 103 | props.enumList ?? [], | 103 | props.enumList ?? [], |
| 104 | props.aliasList ?? [], | 104 | props.aliasList ?? [], |
| 105 | props.enumProvider ?? null, | 105 | props.enumProvider ?? null, |
| 106 | props.forceEnum ?? true, | 106 | props.forceEnum ?? false, |
| 107 | ); | 107 | ); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| @@ -120,9 +120,9 @@ export class SlashCommandNamedArgument extends SlashCommandArgument { | |||
| 120 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} [enums=[]] | 120 | * @param {string|SlashCommandEnumValue|(string|SlashCommandEnumValue)[]} [enums=[]] |
| 121 | * @param {string[]} [aliases=[]] | 121 | * @param {string[]} [aliases=[]] |
| 122 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} [enumProvider=null] function that returns auto complete options | 122 | * @param {(executor:SlashCommandExecutor)=>SlashCommandEnumValue[]} [enumProvider=null] function that returns auto complete options |
| 123 | * @param {boolean} [forceEnum=true] | 123 | * @param {boolean} [forceEnum=false] |
| 124 | */ | 124 | */ |
| 125 | constructor(name, description, types, isRequired = false, acceptsMultiple = false, defaultValue = null, enums = [], aliases = [], enumProvider = null, forceEnum = true) { | 125 | constructor(name, description, types, isRequired = false, acceptsMultiple = false, defaultValue = null, enums = [], aliases = [], enumProvider = null, forceEnum = false) { |
| 126 | super(description, types, isRequired, acceptsMultiple, defaultValue, enums, enumProvider, forceEnum); | 126 | super(description, types, isRequired, acceptsMultiple, defaultValue, enums, enumProvider, forceEnum); |
| 127 | this.name = name; | 127 | this.name = name; |
| 128 | this.aliasList = aliases ? Array.isArray(aliases) ? aliases : [aliases] : []; | 128 | this.aliasList = aliases ? Array.isArray(aliases) ? aliases : [aliases] : []; |
| @@ -43,7 +43,11 @@ router.post('/caption-image', jsonParser, async (request, response) => { | |||
| 43 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); | 43 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | if (!key && !request.body.reverse_proxy && ['custom', 'ooba', 'koboldcpp'].includes(request.body.api) === false) { | 46 | if (request.body.api === 'vllm') { |
| 47 | key = readSecret(request.user.directories, SECRET_KEYS.VLLM); | ||
| 48 | } | ||
| 49 | |||
| 50 | if (!key && !request.body.reverse_proxy && ['custom', 'ooba', 'koboldcpp', 'vllm'].includes(request.body.api) === false) { | ||
| 47 | console.log('No key found for API', request.body.api); | 51 | console.log('No key found for API', request.body.api); |
| 48 | return response.sendStatus(400); | 52 | return response.sendStatus(400); |
| 49 | } | 53 | } |
| @@ -110,7 +114,7 @@ router.post('/caption-image', jsonParser, async (request, response) => { | |||
| 110 | }); | 114 | }); |
| 111 | } | 115 | } |
| 112 | 116 | ||
| 113 | if (request.body.api === 'koboldcpp') { | 117 | if (request.body.api === 'koboldcpp' || request.body.api === 'vllm') { |
| 114 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; | 118 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; |
| 115 | } | 119 | } |
| 116 | 120 | ||