Merge pull request #3561 from SillyTavern/fix-syncing-swipe-data Fix syncing swipe data on reasoning parse & utility function to sync swipe data

7b55d91d35e9de0b74624abca8899c1851337b4d

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

Signed
3 files changed, +59 -14Showing whitespace changes
public/script.js+52 -10
@@ -6086,17 +6086,52 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
6086 return { type, getMessage };6086 return { type, getMessage };
6087}6087}
60886088
6089export function syncCurrentSwipeInfoExtras() {6089/**
6090 * Syncs the current message and all its data into the swipe data at the given message ID (or the last message if no ID is given).
6091 *
6092 * If the swipe data is invalid in some way, this function will exit out without doing anything.
6093 * @param {number?} [messageId=null] - The ID of the message to sync with the swipe data. If no ID is given, the last message is used.
6094 * @returns {boolean} Whether the message was successfully synced
6095 */
6096export function syncMesToSwipe(messageId = null) {
6090 if (!chat.length) {6097 if (!chat.length) {
6091 return;6098 return false;
6092 }6099 }
6093 const currentMessage = chat[chat.length - 1];6100
6094 if (currentMessage && Array.isArray(currentMessage.swipe_info) && typeof currentMessage.swipe_id === 'number') {6101 const targetMessageId = messageId ?? chat.length - 1;
6095 const swipeInfo = currentMessage.swipe_info[currentMessage.swipe_id];6102 if (chat.length > targetMessageId || targetMessageId < 0) {
6096 if (swipeInfo && typeof swipeInfo === 'object') {6103 console.warn(`[syncMesToSwipe] Invalid message ID: ${messageId}`);
6097 swipeInfo.extra = structuredClone(currentMessage.extra);6104 return false;
6098 }6105 }
6106
6107 const targetMessage = chat[targetMessageId];
6108
6109 // No swipe data there yet, exit out
6110 if (typeof targetMessage.swipe_id !== 'number') {
6111 return false;
6099 }6112 }
6113 // If swipes structure is invalid, exit out (for now?)
6114 if (!Array.isArray(targetMessage.swipe_info) || !Array.isArray(targetMessage.swipes)) {
6115 return false;
6116 }
6117 // If the swipe is not present yet, exit out (will likely be copied later)
6118 if (!targetMessage.swipes[targetMessage.swipe_id] || !targetMessage.swipe_info[targetMessage.swipe_id]) {
6119 return false;
6120 }
6121
6122 const targetSwipeInfo = targetMessage.swipe_info[targetMessage.swipe_id];
6123 if (typeof targetSwipeInfo !== 'object') {
6124 return false;
6125 }
6126
6127 targetMessage.swipes[targetMessage.swipe_id] = targetMessage.mes;
6128
6129 targetSwipeInfo.send_date = targetMessage.send_date;
6130 targetSwipeInfo.gen_started = targetMessage.gen_started;
6131 targetSwipeInfo.gen_finished = targetMessage.gen_finished;
6132 targetSwipeInfo.extra = structuredClone(targetMessage.extra);
6133
6134 return true;
6100}6135}
61016136
6102function saveImageToMessage(img, mes) {6137function saveImageToMessage(img, mes) {
@@ -6401,6 +6436,7 @@ export function saveChatDebounced() {
6401 if (chatSaveTimeout) {6436 if (chatSaveTimeout) {
6402 console.debug('Clearing chat save timeout');6437 console.debug('Clearing chat save timeout');
6403 clearTimeout(chatSaveTimeout);6438 clearTimeout(chatSaveTimeout);
6439 chatSaveTimeout = null;
6404 }6440 }
64056441
6406 chatSaveTimeout = setTimeout(async () => {6442 chatSaveTimeout = setTimeout(async () => {
@@ -6417,7 +6453,7 @@ export function saveChatDebounced() {
6417 console.debug('Chat save timeout triggered');6453 console.debug('Chat save timeout triggered');
6418 await saveChatConditional();6454 await saveChatConditional();
6419 console.debug('Chat saved');6455 console.debug('Chat saved');
6420 }, 1000);6456 }, DEFAULT_SAVE_EDIT_TIMEOUT);
6421}6457}
64226458
6423export async function saveChat(chatName, withMetadata, mesId) {6459export async function saveChat(chatName, withMetadata, mesId) {
@@ -8032,6 +8068,12 @@ export async function saveChatConditional() {
8032 }8068 }
80338069
8034 try {8070 try {
8071 if (chatSaveTimeout) {
8072 console.debug('Debounced chat save canceled');
8073 clearTimeout(chatSaveTimeout);
8074 chatSaveTimeout = null;
8075 }
8076
8035 isChatSaving = true;8077 isChatSaving = true;
80368078
8037 if (selected_group) {8079 if (selected_group) {
@@ -8568,7 +8610,7 @@ function swipe_left() { // when we swipe left..but no generation.
8568 }8610 }
85698611
8570 // Make sure ad-hoc changes to extras are saved before swiping away8612 // Make sure ad-hoc changes to extras are saved before swiping away
8571 syncCurrentSwipeInfoExtras();8613 syncMesToSwipe();
85728614
8573 const swipe_duration = 120;8615 const swipe_duration = 120;
8574 const swipe_range = '700px';8616 const swipe_range = '700px';
@@ -8706,7 +8748,7 @@ const swipe_right = () => {
8706 }8748 }
87078749
8708 // Make sure ad-hoc changes to extras are saved before swiping away8750 // Make sure ad-hoc changes to extras are saved before swiping away
8709 syncCurrentSwipeInfoExtras();8751 syncMesToSwipe();
87108752
8711 const swipe_duration = 200;8753 const swipe_duration = 200;
8712 const swipe_range = 700;8754 const swipe_range = 700;
public/scripts/reasoning.js+5 -2
@@ -1,7 +1,7 @@
1import {1import {
2 moment,2 moment,
3} from '../lib.js';3} from '../lib.js';
4import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, updateMessageBlock } from '../script.js';4import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, syncMesToSwipe, updateMessageBlock } from '../script.js';
5import { getRegexedString, regex_placement } from './extensions/regex/engine.js';5import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
6import { getCurrentLocale, t, translate } from './i18n.js';6import { getCurrentLocale, t, translate } from './i18n.js';
7import { MacrosParser } from './macros.js';7import { MacrosParser } from './macros.js';
@@ -1046,8 +1046,11 @@ function registerReasoningAppEvents() {
1046 message.mes = parsedReasoning.content;1046 message.mes = parsedReasoning.content;
1047 }1047 }
10481048
1049 // Find if a message already exists in DOM and must be updated
1050 if (contentUpdated) {1049 if (contentUpdated) {
1050 syncMesToSwipe();
1051 saveChatDebounced();
1052
1053 // Find if a message already exists in DOM and must be updated
1051 const messageRendered = document.querySelector(`.mes[mesid="${idx}"]`) !== null;1054 const messageRendered = document.querySelector(`.mes[mesid="${idx}"]`) !== null;
1052 if (messageRendered) {1055 if (messageRendered) {
1053 console.debug('[Reasoning] Updating message block', idx);1056 console.debug('[Reasoning] Updating message block', idx);
public/scripts/slash-commands.js+2 -2
@@ -42,7 +42,7 @@ import {
42 showMoreMessages,42 showMoreMessages,
43 stopGeneration,43 stopGeneration,
44 substituteParams,44 substituteParams,
45 syncCurrentSwipeInfoExtras,45 syncMesToSwipe,
46 system_avatar,46 system_avatar,
47 system_message_types,47 system_message_types,
48 this_chid,48 this_chid,
@@ -2921,7 +2921,7 @@ async function addSwipeCallback(args, value) {
29212921
2922 if (isTrueBoolean(args.switch)) {2922 if (isTrueBoolean(args.switch)) {
2923 // Make sure ad-hoc changes to extras are saved before swiping away2923 // Make sure ad-hoc changes to extras are saved before swiping away
2924 syncCurrentSwipeInfoExtras();2924 syncMesToSwipe();
2925 lastMessage.swipe_id = newSwipeId;2925 lastMessage.swipe_id = newSwipeId;
2926 lastMessage.mes = lastMessage.swipes[newSwipeId];2926 lastMessage.mes = lastMessage.swipes[newSwipeId];
2927 lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {});2927 lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {});