Merge pull request #2465 from SillyTavern/stop-gen-slash-command /stop slash command to stop generation

7820ec66b92cea4c72e017ba705bdb12a30766da

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

Signed
2 files changed, +48 -11Ignore whitespace
public/script.js+29 -11
@@ -227,7 +227,7 @@ import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, de
227import { initPresetManager } from './scripts/preset-manager.js';227import { initPresetManager } from './scripts/preset-manager.js';
228import { MacrosParser, evaluateMacros } from './scripts/macros.js';228import { MacrosParser, evaluateMacros } from './scripts/macros.js';
229import { currentUser, setUserControls } from './scripts/user.js';229import { currentUser, setUserControls } from './scripts/user.js';
230import { POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';230import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
231import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';231import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
232import { ScraperManager } from './scripts/scrapers.js';232import { ScraperManager } from './scripts/scrapers.js';
233import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';233import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
@@ -520,6 +520,7 @@ const chatElement = $('#chat');
520let dialogueResolve = null;520let dialogueResolve = null;
521let dialogueCloseStop = false;521let dialogueCloseStop = false;
522export let chat_metadata = {};522export let chat_metadata = {};
523/** @type {StreamingProcessor} */
523export let streamingProcessor = null;524export let streamingProcessor = null;
524let crop_data = undefined;525let crop_data = undefined;
525let is_delete_mode = false;526let is_delete_mode = false;
@@ -837,6 +838,7 @@ export let main_api;// = "kobold";
837//novel settings838//novel settings
838export let novelai_settings;839export let novelai_settings;
839export let novelai_setting_names;840export let novelai_setting_names;
841/** @type {AbortController} */
840let abortController;842let abortController;
841843
842//css844//css
@@ -4381,6 +4383,25 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4381}4383}
43824384
4383/**4385/**
4386 * Stops the generation and any streaming if it is currently running.
4387 */
4388export 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 messages4406 * @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 * @returns7187 * @returns {Promise<any>} A promise that resolves when the popup is closed.
7188 * @deprecated Use `callGenericPopup` instead.
7167 */7189 */
7168export function callPopup(text, type, inputValue = '', { okButton, rows, wide, wider, large, allowHorizontalScrolling, allowVerticalScrolling, cropAspect } = {}) {7190export 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 extensions7872 * @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};
78547879
@@ -10342,15 +10367,7 @@ jQuery(async function () {
10342 });10367 });
1034310368
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 });
1035510372
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 () {
1083910856
10840 initCustomSelectedSamplers();10857 initCustomSelectedSamplers();
10841});10858});
10859
public/scripts/slash-commands.js+19 -0
@@ -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: [