mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Fix recursive QR auto-execution
This commit is contained in:
		| @@ -600,6 +600,10 @@ function saveQROrder() { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | let onMessageSentExecuting = false; | ||||||
|  | let onMessageReceivedExecuting = false; | ||||||
|  | let onChatChangedExecuting = false; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Executes quick replies on message received. |  * Executes quick replies on message received. | ||||||
|  * @param {number} index New message index |  * @param {number} index New message index | ||||||
| @@ -608,14 +612,21 @@ function saveQROrder() { | |||||||
| async function onMessageReceived(index) { | async function onMessageReceived(index) { | ||||||
|     if (!extension_settings.quickReply.quickReplyEnabled) return; |     if (!extension_settings.quickReply.quickReplyEnabled) return; | ||||||
|  |  | ||||||
|     for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { |     if (onMessageReceivedExecuting) return; | ||||||
|         const qr = extension_settings.quickReply.quickReplySlots[i]; |  | ||||||
|         if (qr?.autoExecute_botMessage) { |     try { | ||||||
|             const message = getContext().chat[index]; |         onMessageReceivedExecuting = true; | ||||||
|             if (message?.mes && message?.mes !== '...') { |         for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { | ||||||
|                 await sendQuickReply(i); |             const qr = extension_settings.quickReply.quickReplySlots[i]; | ||||||
|  |             if (qr?.autoExecute_botMessage) { | ||||||
|  |                 const message = getContext().chat[index]; | ||||||
|  |                 if (message?.mes && message?.mes !== '...') { | ||||||
|  |                     await sendQuickReply(i); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } finally { | ||||||
|  |         onMessageReceivedExecuting = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -627,14 +638,21 @@ async function onMessageReceived(index) { | |||||||
| async function onMessageSent(index) { | async function onMessageSent(index) { | ||||||
|     if (!extension_settings.quickReply.quickReplyEnabled) return; |     if (!extension_settings.quickReply.quickReplyEnabled) return; | ||||||
|  |  | ||||||
|     for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { |     if (onMessageSentExecuting) return; | ||||||
|         const qr = extension_settings.quickReply.quickReplySlots[i]; |  | ||||||
|         if (qr?.autoExecute_userMessage) { |     try { | ||||||
|             const message = getContext().chat[index]; |         onMessageSentExecuting = true; | ||||||
|             if (message?.mes && message?.mes !== '...') { |         for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { | ||||||
|                 await sendQuickReply(i); |             const qr = extension_settings.quickReply.quickReplySlots[i]; | ||||||
|  |             if (qr?.autoExecute_userMessage) { | ||||||
|  |                 const message = getContext().chat[index]; | ||||||
|  |                 if (message?.mes && message?.mes !== '...') { | ||||||
|  |                     await sendQuickReply(i); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } finally { | ||||||
|  |         onMessageSentExecuting = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -646,11 +664,18 @@ async function onMessageSent(index) { | |||||||
| async function onChatChanged(chatId) { | async function onChatChanged(chatId) { | ||||||
|     if (!extension_settings.quickReply.quickReplyEnabled) return; |     if (!extension_settings.quickReply.quickReplyEnabled) return; | ||||||
|  |  | ||||||
|     for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { |     if (onChatChangedExecuting) return; | ||||||
|         const qr = extension_settings.quickReply.quickReplySlots[i]; |  | ||||||
|         if (qr?.autoExecute_chatLoad && chatId) { |     try { | ||||||
|             await sendQuickReply(i); |         onChatChangedExecuting = true; | ||||||
|  |         for (let i = 0; i < extension_settings.quickReply.numberOfSlots; i++) { | ||||||
|  |             const qr = extension_settings.quickReply.quickReplySlots[i]; | ||||||
|  |             if (qr?.autoExecute_chatLoad && chatId) { | ||||||
|  |                 await sendQuickReply(i); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |     } finally { | ||||||
|  |         onChatChangedExecuting = false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1981,13 +1981,13 @@ function doNewChat() { | |||||||
|     }, 1); |     }, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| function doRandomChat() { | async function doRandomChat() { | ||||||
|     resetSelectedGroup(); |     resetSelectedGroup(); | ||||||
|     setCharacterId(Math.floor(Math.random() * characters.length).toString()); |     const characterId = Math.floor(Math.random() * characters.length).toString(); | ||||||
|     setTimeout(() => { |     setCharacterId(characterId); | ||||||
|         reloadCurrentChat(); |     await delay(1); | ||||||
|     }, 1); |     await reloadCurrentChat(); | ||||||
|  |     return characters[characterId]?.name; | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -686,14 +686,14 @@ async function hideMessageCallback(_, arg) { | |||||||
| async function unhideMessageCallback(_, arg) { | async function unhideMessageCallback(_, arg) { | ||||||
|     if (!arg) { |     if (!arg) { | ||||||
|         console.warn('WARN: No argument provided for /unhide command'); |         console.warn('WARN: No argument provided for /unhide command'); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const range = stringToRange(arg, 0, chat.length - 1); |     const range = stringToRange(arg, 0, chat.length - 1); | ||||||
|  |  | ||||||
|     if (!range) { |     if (!range) { | ||||||
|         console.warn(`WARN: Invalid range provided for /unhide command: ${arg}`); |         console.warn(`WARN: Invalid range provided for /unhide command: ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (let messageId = range.start; messageId <= range.end; messageId++) { |     for (let messageId = range.start; messageId <= range.end; messageId++) { | ||||||
| @@ -701,128 +701,136 @@ async function unhideMessageCallback(_, arg) { | |||||||
|  |  | ||||||
|         if (!messageBlock.length) { |         if (!messageBlock.length) { | ||||||
|             console.warn(`WARN: No message found with ID ${messageId}`); |             console.warn(`WARN: No message found with ID ${messageId}`); | ||||||
|             return; |             return ''; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         await unhideChatMessage(messageId, messageBlock); |         await unhideChatMessage(messageId, messageBlock); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function disableGroupMemberCallback(_, arg) { | async function disableGroupMemberCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /disable command outside of a group chat."); |         toastr.warning("Cannot run /disable command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="disable"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="disable"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function enableGroupMemberCallback(_, arg) { | async function enableGroupMemberCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /enable command outside of a group chat."); |         toastr.warning("Cannot run /enable command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="enable"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="enable"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function moveGroupMemberUpCallback(_, arg) { | async function moveGroupMemberUpCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /memberup command outside of a group chat."); |         toastr.warning("Cannot run /memberup command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="up"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="up"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function moveGroupMemberDownCallback(_, arg) { | async function moveGroupMemberDownCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /memberdown command outside of a group chat."); |         toastr.warning("Cannot run /memberdown command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="down"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="down"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function peekCallback(_, arg) { | async function peekCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /peek command outside of a group chat."); |         toastr.warning("Cannot run /peek command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (is_group_generating) { |     if (is_group_generating) { | ||||||
|         toastr.warning("Cannot run /peek command while the group reply is generating."); |         toastr.warning("Cannot run /peek command while the group reply is generating."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="view"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="view"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function removeGroupMemberCallback(_, arg) { | async function removeGroupMemberCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /memberremove command outside of a group chat."); |         toastr.warning("Cannot run /memberremove command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (is_group_generating) { |     if (is_group_generating) { | ||||||
|         toastr.warning("Cannot run /memberremove command while the group reply is generating."); |         toastr.warning("Cannot run /memberremove command while the group reply is generating."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const chid = findGroupMemberId(arg); |     const chid = findGroupMemberId(arg); | ||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     $(`.group_member[chid="${chid}"] [data-action="remove"]`).trigger('click'); |     $(`.group_member[chid="${chid}"] [data-action="remove"]`).trigger('click'); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function addGroupMemberCallback(_, arg) { | async function addGroupMemberCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /memberadd command outside of a group chat."); |         toastr.warning("Cannot run /memberadd command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!arg) { |     if (!arg) { | ||||||
|         console.warn('WARN: No argument provided for /memberadd command'); |         console.warn('WARN: No argument provided for /memberadd command'); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     arg = arg.trim(); |     arg = arg.trim(); | ||||||
| @@ -830,7 +838,7 @@ async function addGroupMemberCallback(_, arg) { | |||||||
|  |  | ||||||
|     if (chid === -1) { |     if (chid === -1) { | ||||||
|         console.warn(`WARN: No character found for argument ${arg}`); |         console.warn(`WARN: No character found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const character = characters[chid]; |     const character = characters[chid]; | ||||||
| @@ -838,14 +846,14 @@ async function addGroupMemberCallback(_, arg) { | |||||||
|  |  | ||||||
|     if (!group || !Array.isArray(group.members)) { |     if (!group || !Array.isArray(group.members)) { | ||||||
|         console.warn(`WARN: No group found for ID ${selected_group}`); |         console.warn(`WARN: No group found for ID ${selected_group}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const avatar = character.avatar; |     const avatar = character.avatar; | ||||||
|  |  | ||||||
|     if (group.members.includes(avatar)) { |     if (group.members.includes(avatar)) { | ||||||
|         toastr.warning(`${character.name} is already a member of this group.`); |         toastr.warning(`${character.name} is already a member of this group.`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     group.members.push(avatar); |     group.members.push(avatar); | ||||||
| @@ -853,17 +861,18 @@ async function addGroupMemberCallback(_, arg) { | |||||||
|  |  | ||||||
|     // Trigger to reload group UI |     // Trigger to reload group UI | ||||||
|     $('#rm_button_selected_ch').trigger('click'); |     $('#rm_button_selected_ch').trigger('click'); | ||||||
|  |     return character.name; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function triggerGroupMessageCallback(_, arg) { | async function triggerGroupMessageCallback(_, arg) { | ||||||
|     if (!selected_group) { |     if (!selected_group) { | ||||||
|         toastr.warning("Cannot run /trigger command outside of a group chat."); |         toastr.warning("Cannot run /trigger command outside of a group chat."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (is_group_generating) { |     if (is_group_generating) { | ||||||
|         toastr.warning("Cannot run trigger command while the group reply is generating."); |         toastr.warning("Cannot run trigger command while the group reply is generating."); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Prevent generate recursion |     // Prevent generate recursion | ||||||
| @@ -873,10 +882,11 @@ async function triggerGroupMessageCallback(_, arg) { | |||||||
|  |  | ||||||
|     if (chid === undefined) { |     if (chid === undefined) { | ||||||
|         console.warn(`WARN: No group member found for argument ${arg}`); |         console.warn(`WARN: No group member found for argument ${arg}`); | ||||||
|         return; |         return ''; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Generate('normal', { force_chid: chid }); |     Generate('normal', { force_chid: chid }); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function sendUserMessageCallback(_, text) { | async function sendUserMessageCallback(_, text) { | ||||||
| @@ -888,6 +898,7 @@ async function sendUserMessageCallback(_, text) { | |||||||
|     text = text.trim(); |     text = text.trim(); | ||||||
|     const bias = extractMessageBias(text); |     const bias = extractMessageBias(text); | ||||||
|     await sendMessageAsUser(text, bias); |     await sendMessageAsUser(text, bias); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| async function deleteMessagesByNameCallback(_, name) { | async function deleteMessagesByNameCallback(_, name) { | ||||||
| @@ -922,6 +933,7 @@ async function deleteMessagesByNameCallback(_, name) { | |||||||
|     await reloadCurrentChat(); |     await reloadCurrentChat(); | ||||||
|  |  | ||||||
|     toastr.info(`Deleted ${messagesToDelete.length} messages from ${name}`); |     toastr.info(`Deleted ${messagesToDelete.length} messages from ${name}`); | ||||||
|  |     return ''; | ||||||
| } | } | ||||||
|  |  | ||||||
| function findCharacterIndex(name) { | function findCharacterIndex(name) { | ||||||
| @@ -941,7 +953,7 @@ function findCharacterIndex(name) { | |||||||
|     return -1; |     return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| function goToCharacterCallback(_, name) { | async function goToCharacterCallback(_, name) { | ||||||
|     if (!name) { |     if (!name) { | ||||||
|         console.warn('WARN: No character name provided for /go command'); |         console.warn('WARN: No character name provided for /go command'); | ||||||
|         return; |         return; | ||||||
| @@ -951,18 +963,19 @@ function goToCharacterCallback(_, name) { | |||||||
|     const characterIndex = findCharacterIndex(name); |     const characterIndex = findCharacterIndex(name); | ||||||
|  |  | ||||||
|     if (characterIndex !== -1) { |     if (characterIndex !== -1) { | ||||||
|         openChat(new String(characterIndex)); |         await openChat(new String(characterIndex)); | ||||||
|  |         return characters[characterIndex]?.name; | ||||||
|     } else { |     } else { | ||||||
|         console.warn(`No matches found for name "${name}"`); |         console.warn(`No matches found for name "${name}"`); | ||||||
|  |         return ''; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function openChat(id) { | async function openChat(id) { | ||||||
|     resetSelectedGroup(); |     resetSelectedGroup(); | ||||||
|     setCharacterId(id); |     setCharacterId(id); | ||||||
|     setTimeout(() => { |     await delay(1); | ||||||
|         reloadCurrentChat(); |     await reloadCurrentChat(); | ||||||
|     }, 1); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function continueChatCallback() { | function continueChatCallback() { | ||||||
| @@ -1096,9 +1109,9 @@ export async function sendMessageAs(namedArgs, text) { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     chat.push(message); |     chat.push(message); | ||||||
|     await eventSource.emit(event_types.MESSAGE_SENT, (chat.length - 1)); |     await eventSource.emit(event_types.MESSAGE_RECEIVED, (chat.length - 1)); | ||||||
|     addOneMessage(message); |     addOneMessage(message); | ||||||
|     await eventSource.emit(event_types.USER_MESSAGE_RENDERED, (chat.length - 1)); |     await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, (chat.length - 1)); | ||||||
|     await saveChatConditional(); |     await saveChatConditional(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user