Merge pull request #2465 from SillyTavern/stop-gen-slash-command /stop slash command to stop generation
Signed| @@ -227,7 +227,7 @@ import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, de | |||
| 227 | import { initPresetManager } from './scripts/preset-manager.js'; | 227 | import { initPresetManager } from './scripts/preset-manager.js'; |
| 228 | import { MacrosParser, evaluateMacros } from './scripts/macros.js'; | 228 | import { MacrosParser, evaluateMacros } from './scripts/macros.js'; |
| 229 | import { currentUser, setUserControls } from './scripts/user.js'; | 229 | import { currentUser, setUserControls } from './scripts/user.js'; |
| 230 | import { POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js'; | 230 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js'; |
| 231 | import { renderTemplate, renderTemplateAsync } from './scripts/templates.js'; | 231 | import { renderTemplate, renderTemplateAsync } from './scripts/templates.js'; |
| 232 | import { ScraperManager } from './scripts/scrapers.js'; | 232 | import { ScraperManager } from './scripts/scrapers.js'; |
| 233 | import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js'; | 233 | import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js'; |
| @@ -520,6 +520,7 @@ const chatElement = $('#chat'); | |||
| 520 | let dialogueResolve = null; | 520 | let dialogueResolve = null; |
| 521 | let dialogueCloseStop = false; | 521 | let dialogueCloseStop = false; |
| 522 | export let chat_metadata = {}; | 522 | export let chat_metadata = {}; |
| 523 | /** @type {StreamingProcessor} */ | ||
| 523 | export let streamingProcessor = null; | 524 | export let streamingProcessor = null; |
| 524 | let crop_data = undefined; | 525 | let crop_data = undefined; |
| 525 | let is_delete_mode = false; | 526 | let is_delete_mode = false; |
| @@ -837,6 +838,7 @@ export let main_api;// = "kobold"; | |||
| 837 | //novel settings | 838 | //novel settings |
| 838 | export let novelai_settings; | 839 | export let novelai_settings; |
| 839 | export let novelai_setting_names; | 840 | export let novelai_setting_names; |
| 841 | /** @type {AbortController} */ | ||
| 840 | let abortController; | 842 | let abortController; |
| 841 | 843 | ||
| 842 | //css | 844 | //css |
| @@ -4381,6 +4383,25 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4381 | } | 4383 | } |
| 4382 | 4384 | ||
| 4383 | /** | 4385 | /** |
| 4386 | * Stops the generation and any streaming if it is currently running. | ||
| 4387 | */ | ||
| 4388 | export function stopGeneration() { | ||
| 4389 | let stopped = false; | ||
| 4390 | if (streamingProcessor) { | ||
| 4391 | streamingProcessor.onStopStreaming(); | ||
| 4392 | streamingProcessor = null; | ||
| 4393 | stopped = true; | ||
| 4394 | } | ||
| 4395 | if (abortController) { | ||
| 4396 | abortController.abort('Clicked stop button'); | ||
| 4397 | hideStopButton(); | ||
| 4398 | stopped = true; | ||
| 4399 | } | ||
| 4400 | eventSource.emit(event_types.GENERATION_STOPPED); | ||
| 4401 | return stopped; | ||
| 4402 | } | ||
| 4403 | |||
| 4404 | /** | ||
| 4384 | * Injects extension prompts into chat messages. | 4405 | * Injects extension prompts into chat messages. |
| 4385 | * @param {object[]} messages Array of chat messages | 4406 | * @param {object[]} messages Array of chat messages |
| 4386 | * @param {boolean} isContinue Whether the generation is a continuation. If true, the extension prompts of depth 0 are injected at position 1. | 4407 | * @param {boolean} isContinue Whether the generation is a continuation. If true, the extension prompts of depth 0 are injected at position 1. |
| @@ -7163,7 +7184,8 @@ function onScenarioOverrideRemoveClick() { | |||
| 7163 | * @param {string} inputValue - Value to set the input to. | 7184 | * @param {string} inputValue - Value to set the input to. |
| 7164 | * @param {PopupOptions} options - Options for the popup. | 7185 | * @param {PopupOptions} options - Options for the popup. |
| 7165 | * @typedef {{okButton?: string, rows?: number, wide?: boolean, wider?: boolean, large?: boolean, allowHorizontalScrolling?: boolean, allowVerticalScrolling?: boolean, cropAspect?: number }} PopupOptions - Options for the popup. | 7186 | * @typedef {{okButton?: string, rows?: number, wide?: boolean, wider?: boolean, large?: boolean, allowHorizontalScrolling?: boolean, allowVerticalScrolling?: boolean, cropAspect?: number }} PopupOptions - Options for the popup. |
| 7166 | * @returns | 7187 | * @returns {Promise<any>} A promise that resolves when the popup is closed. |
| 7188 | * @deprecated Use `callGenericPopup` instead. | ||
| 7167 | */ | 7189 | */ |
| 7168 | export function callPopup(text, type, inputValue = '', { okButton, rows, wide, wider, large, allowHorizontalScrolling, allowVerticalScrolling, cropAspect } = {}) { | 7190 | export function callPopup(text, type, inputValue = '', { okButton, rows, wide, wider, large, allowHorizontalScrolling, allowVerticalScrolling, cropAspect } = {}) { |
| 7169 | function getOkButtonText() { | 7191 | function getOkButtonText() { |
| @@ -7794,6 +7816,7 @@ window['SillyTavern'].getContext = function () { | |||
| 7794 | eventTypes: event_types, | 7816 | eventTypes: event_types, |
| 7795 | addOneMessage: addOneMessage, | 7817 | addOneMessage: addOneMessage, |
| 7796 | generate: Generate, | 7818 | generate: Generate, |
| 7819 | stopGeneration: stopGeneration, | ||
| 7797 | getTokenCount: getTokenCount, | 7820 | getTokenCount: getTokenCount, |
| 7798 | extensionPrompts: extension_prompts, | 7821 | extensionPrompts: extension_prompts, |
| 7799 | setExtensionPrompt: setExtensionPrompt, | 7822 | setExtensionPrompt: setExtensionPrompt, |
| @@ -7849,6 +7872,8 @@ window['SillyTavern'].getContext = function () { | |||
| 7849 | * @deprecated Legacy snake-case naming, compatibility with old extensions | 7872 | * @deprecated Legacy snake-case naming, compatibility with old extensions |
| 7850 | */ | 7873 | */ |
| 7851 | event_types: event_types, | 7874 | event_types: event_types, |
| 7875 | POPUP_TYPE: POPUP_TYPE, | ||
| 7876 | POPUP_RESULT: POPUP_RESULT, | ||
| 7852 | }; | 7877 | }; |
| 7853 | }; | 7878 | }; |
| 7854 | 7879 | ||
| @@ -10342,15 +10367,7 @@ jQuery(async function () { | |||
| 10342 | }); | 10367 | }); |
| 10343 | 10368 | ||
| 10344 | $(document).on('click', '.mes_stop', function () { | 10369 | $(document).on('click', '.mes_stop', function () { |
| 10345 | if (streamingProcessor) { | 10370 | stopGeneration(); |
| 10346 | streamingProcessor.onStopStreaming(); | ||
| 10347 | streamingProcessor = null; | ||
| 10348 | } | ||
| 10349 | if (abortController) { | ||
| 10350 | abortController.abort('Clicked stop button'); | ||
| 10351 | hideStopButton(); | ||
| 10352 | } | ||
| 10353 | eventSource.emit(event_types.GENERATION_STOPPED); | ||
| 10354 | }); | 10371 | }); |
| 10355 | 10372 | ||
| 10356 | $(document).on('click', '#form_sheld .stscript_continue', function () { | 10373 | $(document).on('click', '#form_sheld .stscript_continue', function () { |
| @@ -10839,3 +10856,4 @@ jQuery(async function () { | |||
| 10839 | 10856 | ||
| 10840 | initCustomSelectedSamplers(); | 10857 | initCustomSelectedSamplers(); |
| 10841 | }); | 10858 | }); |
| 10859 | |||
| @@ -33,6 +33,7 @@ import { | |||
| 33 | setCharacterName, | 33 | setCharacterName, |
| 34 | setExtensionPrompt, | 34 | setExtensionPrompt, |
| 35 | setUserName, | 35 | setUserName, |
| 36 | stopGeneration, | ||
| 36 | substituteParams, | 37 | substituteParams, |
| 37 | system_avatar, | 38 | system_avatar, |
| 38 | system_message_types, | 39 | system_message_types, |
| @@ -899,6 +900,24 @@ export function initDefaultSlashCommands() { | |||
| 899 | helpString: 'Adds a swipe to the last chat message.', | 900 | helpString: 'Adds a swipe to the last chat message.', |
| 900 | })); | 901 | })); |
| 901 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 902 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 903 | name: 'stop', | ||
| 904 | callback: () => { | ||
| 905 | const stopped = stopGeneration(); | ||
| 906 | return String(stopped); | ||
| 907 | }, | ||
| 908 | returns: 'true/false, whether the generation was running and got stopped', | ||
| 909 | helpString: ` | ||
| 910 | <div> | ||
| 911 | Stops the generation and any streaming if it is currently running. | ||
| 912 | </div> | ||
| 913 | <div> | ||
| 914 | Note: This command cannot be executed from the chat input, as sending any message or script from there is blocked during generation. | ||
| 915 | But it can be executed via automations or QR scripts/buttons. | ||
| 916 | </div> | ||
| 917 | `, | ||
| 918 | aliases: ['generate-stop'], | ||
| 919 | })); | ||
| 920 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | ||
| 902 | name: 'abort', | 921 | name: 'abort', |
| 903 | callback: abortCallback, | 922 | callback: abortCallback, |
| 904 | namedArgumentList: [ | 923 | namedArgumentList: [ |