Fix currently reswiped messages being returned on macros

- Build one utility function to get the last message id matching a criteria
- Fix all macros referencing last message still returning a now being reswiped message
This commit is contained in:
Wolfsblvt 2024-04-07 00:06:38 +02:00
parent fcc8051d38
commit d5cb4f403a
1 changed files with 64 additions and 83 deletions

View File

@ -7,122 +7,103 @@ import { replaceVariableMacros } from './variables.js';
// Register any macro that you want to leave in the compiled story string // Register any macro that you want to leave in the compiled story string
Handlebars.registerHelper('trim', () => '{{trim}}'); Handlebars.registerHelper('trim', () => '{{trim}}');
/** /**
* Returns the ID of the last message in the chat. * Returns the ID of the last message in the chat
* @returns {string} The ID of the last message in the chat. *
* Optionally can only choose specific messages, if a filter is provided.
*
* @param {object} param0 - Optional arguments
* @param {boolean} [param0.exclude_swipe_in_propress=true] - Whether a message that is currently being swiped should be ignored
* @param {function(object):boolean} [param0.filter] - A filter applied to the search, ignoring all messages that don't match the criteria. For example to only find user messages, etc.
* @returns {number|null} The message id, or null if none was found
*/ */
function getLastMessageId() { export function getLastMessageId({ exclude_swipe_in_propress = true, filter = null } = {}) {
const index = chat?.length - 1; for (let i = chat?.length - 1; i >= 0; i--) {
let message = chat[i];
if (!isNaN(index) && index >= 0) { // If ignoring swipes and the message is being swiped, continue
return String(index); // We can check if a message is being swiped by checking whether the current swipe id is not in the list of finished swipes yet
if (exclude_swipe_in_propress && message.swipes && message.swipe_id >= message.swipes.length) {
continue;
} }
return ''; // Check if no filter is provided, or if the message passes the filter
if (!filter || filter(message)) {
return i;
}
}
return null;
} }
/** /**
* Returns the ID of the first message included in the context. * Returns the ID of the first message included in the context
* @returns {string} The ID of the first message in the context. *
* @returns {number|null} The ID of the first message in the context
*/ */
function getFirstIncludedMessageId() { function getFirstIncludedMessageId() {
const index = document.querySelector('.lastInContext')?.getAttribute('mesid'); const index = Number(document.querySelector('.lastInContext')?.getAttribute('mesid'));
if (!isNaN(index) && index >= 0) { if (!isNaN(index) && index >= 0) {
return String(index); return index;
} }
return ''; return null;
} }
/** /**
* Returns the last message in the chat. * Returns the last message in the chat
* @returns {string} The last message in the chat. *
* @returns {string} The last message in the chat
*/ */
function getLastMessage() { function getLastMessage() {
const index = chat?.length - 1; const mid = getLastMessageId();
return chat[mid]?.mes ?? '';
if (!isNaN(index) && index >= 0) {
return chat[index].mes;
}
return '';
} }
/** /**
* Returns the last message from the user. * Returns the last message from the user
* @returns {string} The last message from the user. *
* @returns {string} The last message from the user
*/ */
function getLastUserMessage() { function getLastUserMessage() {
if (!Array.isArray(chat) || chat.length === 0) { const mid = getLastMessageId({ filter: m => m.is_user && !m.is_system });
return ''; return chat[mid]?.mes ?? '';
}
for (let i = chat.length - 1; i >= 0; i--) {
if (chat[i].is_user && !chat[i].is_system) {
return chat[i].mes;
}
}
return '';
} }
/** /**
* Returns the last message from the bot. * Returns the last message from the bot
* @returns {string} The last message from the bot. *
* @returns {string} The last message from the bot
*/ */
function getLastCharMessage() { function getLastCharMessage() {
if (!Array.isArray(chat) || chat.length === 0) { const mid = getLastMessageId({ filter: m => !m.is_user && !m.is_system });
return ''; return chat[mid]?.mes ?? '';
}
for (let i = chat.length - 1; i >= 0; i--) {
if (!chat[i].is_user && !chat[i].is_system) {
return chat[i].mes;
}
}
return '';
} }
/** /**
* Returns the ID of the last swipe. * Returns the 1-based ID (number) of the last swipe
* @returns {string} The 1-based ID of the last swipe *
* @returns {number|null} The 1-based ID of the last swipe
*/ */
function getLastSwipeId() { function getLastSwipeId() {
const index = chat?.length - 1; // For swipe macro, we are accepting using the message that is currently being swiped
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
if (!isNaN(index) && index >= 0) { const swipes = chat[mid]?.swipes;
const swipes = chat[index].swipes; return swipes?.length;
if (!Array.isArray(swipes) || swipes.length === 0) {
return '';
}
return String(swipes.length);
}
return '';
} }
/** /**
* Returns the ID of the current swipe. * Returns the 1-based ID (number) of the current swipe
* @returns {string} The 1-based ID of the current swipe. *
* @returns {number|null} The 1-based ID of the current swipe
*/ */
function getCurrentSwipeId() { function getCurrentSwipeId() {
const index = chat?.length - 1; // For swipe macro, we are accepting using the message that is currently being swiped
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
if (!isNaN(index) && index >= 0) { const swipeId = chat[mid]?.swipe_id;
const swipeId = chat[index].swipe_id; return swipeId ? swipeId + 1 : null;
if (swipeId === undefined || isNaN(swipeId)) {
return '';
}
return String(swipeId + 1);
}
return '';
} }
/** /**
@ -292,12 +273,12 @@ export function evaluateMacros(content, env) {
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize())); content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
content = content.replace(/{{lastMessage}}/gi, () => getLastMessage()); content = content.replace(/{{lastMessage}}/gi, () => getLastMessage());
content = content.replace(/{{lastMessageId}}/gi, () => getLastMessageId()); content = content.replace(/{{lastMessageId}}/gi, () => String(getLastMessageId() ?? ''));
content = content.replace(/{{lastUserMessage}}/gi, () => getLastUserMessage()); content = content.replace(/{{lastUserMessage}}/gi, () => getLastUserMessage());
content = content.replace(/{{lastCharMessage}}/gi, () => getLastCharMessage()); content = content.replace(/{{lastCharMessage}}/gi, () => getLastCharMessage());
content = content.replace(/{{firstIncludedMessageId}}/gi, () => getFirstIncludedMessageId()); content = content.replace(/{{firstIncludedMessageId}}/gi, () => String(getFirstIncludedMessageId() ?? ''));
content = content.replace(/{{lastSwipeId}}/gi, () => getLastSwipeId()); content = content.replace(/{{lastSwipeId}}/gi, () => String(getLastSwipeId() ?? ''));
content = content.replace(/{{currentSwipeId}}/gi, () => getCurrentSwipeId()); content = content.replace(/{{currentSwipeId}}/gi, () => String(getCurrentSwipeId() ?? ''));
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, ''); content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');