Merge pull request #2656 from SillyTavern/qr-new-chat Quick Replies: Add auto-execute on new chat

c3caee759fe4abda4f9ad30db8f68a56a8aaddab

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

Signed
5 files changed, +33 -0Showing whitespace changes
public/scripts/extensions/quick-reply/api/QuickReplyApi.js+6 -0
@@ -204,6 +204,7 @@ export class QuickReplyApi {
204 * @param {boolean} [props.executeOnAi] whether to execute the quick reply after the AI has sent a message204 * @param {boolean} [props.executeOnAi] whether to execute the quick reply after the AI has sent a message
205 * @param {boolean} [props.executeOnChatChange] whether to execute the quick reply when a new chat is loaded205 * @param {boolean} [props.executeOnChatChange] whether to execute the quick reply when a new chat is loaded
206 * @param {boolean} [props.executeOnGroupMemberDraft] whether to execute the quick reply when a group member is selected206 * @param {boolean} [props.executeOnGroupMemberDraft] whether to execute the quick reply when a group member is selected
207 * @param {boolean} [props.executeOnNewChat] whether to execute the quick reply when a new chat is created
207 * @param {string} [props.automationId] when not empty, the quick reply will be executed when the WI with the given automation ID is activated208 * @param {string} [props.automationId] when not empty, the quick reply will be executed when the WI with the given automation ID is activated
208 * @returns {QuickReply} the new quick reply209 * @returns {QuickReply} the new quick reply
209 */210 */
@@ -218,6 +219,7 @@ export class QuickReplyApi {
218 executeOnAi,219 executeOnAi,
219 executeOnChatChange,220 executeOnChatChange,
220 executeOnGroupMemberDraft,221 executeOnGroupMemberDraft,
222 executeOnNewChat,
221 automationId,223 automationId,
222 } = {}) {224 } = {}) {
223 const set = this.getSetByName(setName);225 const set = this.getSetByName(setName);
@@ -236,6 +238,7 @@ export class QuickReplyApi {
236 qr.executeOnAi = executeOnAi ?? false;238 qr.executeOnAi = executeOnAi ?? false;
237 qr.executeOnChatChange = executeOnChatChange ?? false;239 qr.executeOnChatChange = executeOnChatChange ?? false;
238 qr.executeOnGroupMemberDraft = executeOnGroupMemberDraft ?? false;240 qr.executeOnGroupMemberDraft = executeOnGroupMemberDraft ?? false;
241 qr.executeOnNewChat = executeOnNewChat ?? false;
239 qr.automationId = automationId ?? '';242 qr.automationId = automationId ?? '';
240 qr.onUpdate();243 qr.onUpdate();
241 return qr;244 return qr;
@@ -258,6 +261,7 @@ export class QuickReplyApi {
258 * @param {boolean} [props.executeOnAi] whether to execute the quick reply after the AI has sent a message261 * @param {boolean} [props.executeOnAi] whether to execute the quick reply after the AI has sent a message
259 * @param {boolean} [props.executeOnChatChange] whether to execute the quick reply when a new chat is loaded262 * @param {boolean} [props.executeOnChatChange] whether to execute the quick reply when a new chat is loaded
260 * @param {boolean} [props.executeOnGroupMemberDraft] whether to execute the quick reply when a group member is selected263 * @param {boolean} [props.executeOnGroupMemberDraft] whether to execute the quick reply when a group member is selected
264 * @param {boolean} [props.executeOnNewChat] whether to execute the quick reply when a new chat is created
261 * @param {string} [props.automationId] when not empty, the quick reply will be executed when the WI with the given automation ID is activated265 * @param {string} [props.automationId] when not empty, the quick reply will be executed when the WI with the given automation ID is activated
262 * @returns {QuickReply} the altered quick reply266 * @returns {QuickReply} the altered quick reply
263 */267 */
@@ -273,6 +277,7 @@ export class QuickReplyApi {
273 executeOnAi,277 executeOnAi,
274 executeOnChatChange,278 executeOnChatChange,
275 executeOnGroupMemberDraft,279 executeOnGroupMemberDraft,
280 executeOnNewChat,
276 automationId,281 automationId,
277 } = {}) {282 } = {}) {
278 const qr = this.getQrByLabel(setName, label);283 const qr = this.getQrByLabel(setName, label);
@@ -290,6 +295,7 @@ export class QuickReplyApi {
290 qr.executeOnAi = executeOnAi ?? qr.executeOnAi;295 qr.executeOnAi = executeOnAi ?? qr.executeOnAi;
291 qr.executeOnChatChange = executeOnChatChange ?? qr.executeOnChatChange;296 qr.executeOnChatChange = executeOnChatChange ?? qr.executeOnChatChange;
292 qr.executeOnGroupMemberDraft = executeOnGroupMemberDraft ?? qr.executeOnGroupMemberDraft;297 qr.executeOnGroupMemberDraft = executeOnGroupMemberDraft ?? qr.executeOnGroupMemberDraft;
298 qr.executeOnNewChat = executeOnNewChat ?? qr.executeOnNewChat;
293 qr.automationId = automationId ?? qr.automationId;299 qr.automationId = automationId ?? qr.automationId;
294 qr.onUpdate();300 qr.onUpdate();
295 return qr;301 return qr;
public/scripts/extensions/quick-reply/html/qrEditor.html+4 -0
@@ -109,6 +109,10 @@
109 <span><i class="fa-solid fa-fw fa-message"></i><span data-i18n="Execute on chat change">Execute on chat change</span></span>109 <span><i class="fa-solid fa-fw fa-message"></i><span data-i18n="Execute on chat change">Execute on chat change</span></span>
110 </label>110 </label>
111 <label class="checkbox_label">111 <label class="checkbox_label">
112 <input type="checkbox" id="qr--executeOnNewChat">
113 <span><i class="fa-solid fa-fw fa-comments"></i><span data-i18n="Execute on new chat">Execute on new chat</span></span>
114 </label>
115 <label class="checkbox_label">
112 <input type="checkbox" id="qr--executeOnGroupMemberDraft">116 <input type="checkbox" id="qr--executeOnGroupMemberDraft">
113 <span><i class="fa-solid fa-fw fa-people-group"></i><span data-i18n="Execute on group member draft">Execute on group member draft</span></span>117 <span><i class="fa-solid fa-fw fa-people-group"></i><span data-i18n="Execute on group member draft">Execute on group member draft</span></span>
114 </label>118 </label>
public/scripts/extensions/quick-reply/index.js+6 -0
@@ -105,6 +105,7 @@ const loadSets = async () => {
105 qr.executeOnAi = slot.autoExecute_botMessage ?? false;105 qr.executeOnAi = slot.autoExecute_botMessage ?? false;
106 qr.executeOnChatChange = slot.autoExecute_chatLoad ?? false;106 qr.executeOnChatChange = slot.autoExecute_chatLoad ?? false;
107 qr.executeOnGroupMemberDraft = slot.autoExecute_groupMemberDraft ?? false;107 qr.executeOnGroupMemberDraft = slot.autoExecute_groupMemberDraft ?? false;
108 qr.executeOnNewChat = slot.autoExecute_newChat ?? false;
108 qr.automationId = slot.automationId ?? '';109 qr.automationId = slot.automationId ?? '';
109 qr.contextList = (slot.contextMenu ?? []).map(it=>({110 qr.contextList = (slot.contextMenu ?? []).map(it=>({
110 set: it.preset,111 set: it.preset,
@@ -260,3 +261,8 @@ const onWIActivation = async (entries) => {
260 await autoExec.handleWIActivation(entries);261 await autoExec.handleWIActivation(entries);
261};262};
262eventSource.on(event_types.WORLD_INFO_ACTIVATED, (...args) => executeIfReadyElseQueue(onWIActivation, args));263eventSource.on(event_types.WORLD_INFO_ACTIVATED, (...args) => executeIfReadyElseQueue(onWIActivation, args));
264
265const onNewChat = async () => {
266 await autoExec.handleNewChat();
267};
268eventSource.on(event_types.CHAT_CREATED, (...args) => executeIfReadyElseQueue(onNewChat, args));
public/scripts/extensions/quick-reply/src/AutoExecuteHandler.js+9 -0
@@ -83,6 +83,15 @@ export class AutoExecuteHandler {
83 await this.performAutoExecute(qrList);83 await this.performAutoExecute(qrList);
84 }84 }
8585
86 async handleNewChat() {
87 if (!this.checkExecute()) return;
88 const qrList = [
89 ...this.settings.config.setList.map(link=>link.set.qrList.filter(qr=>qr.executeOnNewChat)).flat(),
90 ...(this.settings.chatConfig?.setList?.map(link=>link.set.qrList.filter(qr=>qr.executeOnNewChat))?.flat() ?? []),
91 ];
92 await this.performAutoExecute(qrList);
93 }
94
86 /**95 /**
87 * @param {any[]} entries Set of activated entries96 * @param {any[]} entries Set of activated entries
88 */97 */
public/scripts/extensions/quick-reply/src/QuickReply.js+8 -0
@@ -44,6 +44,7 @@ export class QuickReply {
44 /**@type {boolean}*/ executeOnAi = false;44 /**@type {boolean}*/ executeOnAi = false;
45 /**@type {boolean}*/ executeOnChatChange = false;45 /**@type {boolean}*/ executeOnChatChange = false;
46 /**@type {boolean}*/ executeOnGroupMemberDraft = false;46 /**@type {boolean}*/ executeOnGroupMemberDraft = false;
47 /**@type {boolean}*/ executeOnNewChat = false;
47 /**@type {string}*/ automationId = '';48 /**@type {string}*/ automationId = '';
4849
49 /**@type {function}*/ onExecute;50 /**@type {function}*/ onExecute;
@@ -1061,6 +1062,13 @@ export class QuickReply {
1061 this.updateContext();1062 this.updateContext();
1062 });1063 });
1063 /**@type {HTMLInputElement}*/1064 /**@type {HTMLInputElement}*/
1065 const executeOnNewChat = dom.querySelector('#qr--executeOnNewChat');
1066 executeOnNewChat.checked = this.executeOnNewChat;
1067 executeOnNewChat.addEventListener('click', ()=>{
1068 this.executeOnNewChat = executeOnNewChat.checked;
1069 this.updateContext();
1070 });
1071 /**@type {HTMLInputElement}*/
1064 const automationId = dom.querySelector('#qr--automationId');1072 const automationId = dom.querySelector('#qr--automationId');
1065 automationId.value = this.automationId;1073 automationId.value = this.automationId;
1066 automationId.addEventListener('input', () => {1074 automationId.addEventListener('input', () => {