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
Handlebars.registerHelper('trim', () => '{{trim}}');
/**
* Returns the ID of the last message in the chat.
* @returns {string} The ID of the last message in the chat.
*/
function getLastMessageId() {
const index = chat?.length - 1;
if (!isNaN(index) && index >= 0) {
return String(index);
/**
* Returns 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
*/
export function getLastMessageId({ exclude_swipe_in_propress = true, filter = null } = {}) {
for (let i = chat?.length - 1; i >= 0; i--) {
let message = chat[i];
// If ignoring swipes and the message is being swiped, continue
// 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;
}
// Check if no filter is provided, or if the message passes the filter
if (!filter || filter(message)) {
return i;
}
}
return '';
return null;
}
/**
* Returns the ID of the first message included in the context.
* @returns {string} The ID of the first message in the context.
* Returns the ID of the first message included in the context
*
* @returns {number|null} The ID of the first message in the context
*/
function getFirstIncludedMessageId() {
const index = document.querySelector('.lastInContext')?.getAttribute('mesid');
const index = Number(document.querySelector('.lastInContext')?.getAttribute('mesid'));
if (!isNaN(index) && index >= 0) {
return String(index);
return index;
}
return '';
return null;
}
/**
* Returns the last message in the chat.
* @returns {string} The last message in the chat.
* Returns the last message in the chat
*
* @returns {string} The last message in the chat
*/
function getLastMessage() {
const index = chat?.length - 1;
if (!isNaN(index) && index >= 0) {
return chat[index].mes;
}
return '';
const mid = getLastMessageId();
return chat[mid]?.mes ?? '';
}
/**
* Returns the last message from the user.
* @returns {string} The last message from the user.
* Returns the last message from the user
*
* @returns {string} The last message from the user
*/
function getLastUserMessage() {
if (!Array.isArray(chat) || chat.length === 0) {
return '';
}
for (let i = chat.length - 1; i >= 0; i--) {
if (chat[i].is_user && !chat[i].is_system) {
return chat[i].mes;
}
}
return '';
const mid = getLastMessageId({ filter: m => m.is_user && !m.is_system });
return chat[mid]?.mes ?? '';
}
/**
* Returns the last message from the bot.
* @returns {string} The last message from the bot.
* Returns the last message from the bot
*
* @returns {string} The last message from the bot
*/
function getLastCharMessage() {
if (!Array.isArray(chat) || chat.length === 0) {
return '';
}
for (let i = chat.length - 1; i >= 0; i--) {
if (!chat[i].is_user && !chat[i].is_system) {
return chat[i].mes;
}
}
return '';
const mid = getLastMessageId({ filter: m => !m.is_user && !m.is_system });
return chat[mid]?.mes ?? '';
}
/**
* Returns the ID of the last swipe.
* @returns {string} The 1-based ID of the last swipe
* Returns the 1-based ID (number) of the last swipe
*
* @returns {number|null} The 1-based ID of the last swipe
*/
function getLastSwipeId() {
const index = chat?.length - 1;
if (!isNaN(index) && index >= 0) {
const swipes = chat[index].swipes;
if (!Array.isArray(swipes) || swipes.length === 0) {
return '';
}
return String(swipes.length);
}
return '';
// For swipe macro, we are accepting using the message that is currently being swiped
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
const swipes = chat[mid]?.swipes;
return swipes?.length;
}
/**
* Returns the ID of the current swipe.
* @returns {string} The 1-based ID of the current swipe.
* Returns the 1-based ID (number) of the current swipe
*
* @returns {number|null} The 1-based ID of the current swipe
*/
function getCurrentSwipeId() {
const index = chat?.length - 1;
if (!isNaN(index) && index >= 0) {
const swipeId = chat[index].swipe_id;
if (swipeId === undefined || isNaN(swipeId)) {
return '';
}
return String(swipeId + 1);
}
return '';
// For swipe macro, we are accepting using the message that is currently being swiped
const mid = getLastMessageId({ exclude_swipe_in_propress: false });
const swipeId = chat[mid]?.swipe_id;
return swipeId ? swipeId + 1 : null;
}
/**
@ -292,12 +273,12 @@ export function evaluateMacros(content, env) {
content = content.replace(/{{maxPrompt}}/gi, () => String(getMaxContextSize()));
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(/{{lastCharMessage}}/gi, () => getLastCharMessage());
content = content.replace(/{{firstIncludedMessageId}}/gi, () => getFirstIncludedMessageId());
content = content.replace(/{{lastSwipeId}}/gi, () => getLastSwipeId());
content = content.replace(/{{currentSwipeId}}/gi, () => getCurrentSwipeId());
content = content.replace(/{{firstIncludedMessageId}}/gi, () => String(getFirstIncludedMessageId() ?? ''));
content = content.replace(/{{lastSwipeId}}/gi, () => String(getLastSwipeId() ?? ''));
content = content.replace(/{{currentSwipeId}}/gi, () => String(getCurrentSwipeId() ?? ''));
content = content.replace(/\{\{\/\/([\s\S]*?)\}\}/gm, '');