From 6fc342d446f8bf6368852c0a2528c901a6e0a1b7 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:06:07 +0200 Subject: [PATCH 1/5] Add regex processing for reasoning blocks --- public/script.js | 59 +++++++++++++++------ public/scripts/extensions/regex/editor.html | 6 +++ public/scripts/extensions/regex/engine.js | 1 + 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/public/script.js b/public/script.js index 006f946d7..09d7a921b 100644 --- a/public/script.js +++ b/public/script.js @@ -1993,9 +1993,10 @@ export async function sendTextareaMessage() { * @param {boolean} isUser If the message was sent by the user * @param {number} messageId Message index in chat array * @param {object} [sanitizerOverrides] DOMPurify sanitizer option overrides + * @param {boolean} [isReasoning] If the message is reasoning output * @returns {string} HTML string */ -export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, sanitizerOverrides = {}) { +export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, sanitizerOverrides = {}, isReasoning = false) { if (!mes) { return ''; } @@ -2029,6 +2030,9 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId, san if (!isSystem) { function getRegexPlacement() { try { + if (isReasoning) { + return regex_placement.REASONING; + } if (isUser) { return regex_placement.USER_INPUT; } else if (chat[messageId]?.extra?.type === 'narrator') { @@ -2250,8 +2254,8 @@ function getMessageFromTemplate({ export function updateMessageBlock(messageId, message) { const messageElement = $(`#chat [mesid="${messageId}"]`); const text = message?.extra?.display_text ?? message.mes; - messageElement.find('.mes_text').html(messageFormatting(text, message.name, message.is_system, message.is_user, messageId)); - messageElement.find('.mes_reasoning').html(messageFormatting(message.extra?.reasoning ?? '', '', false, false, -1)); + messageElement.find('.mes_text').html(messageFormatting(text, message.name, message.is_system, message.is_user, messageId, {}, false)); + messageElement.find('.mes_reasoning').html(messageFormatting(message.extra?.reasoning ?? '', '', false, false, messageId, {}, true)); addCopyToCodeBlocks(messageElement); appendMediaToMessage(message, messageElement); } @@ -2408,9 +2412,10 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll mes.is_user, chat.indexOf(mes), sanitizerOverrides, + false, ); - const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1); - const reasoning = messageFormatting(mes.extra?.reasoning ?? '', '', false, false, -1); + const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1, {}, false); + const reasoning = messageFormatting(mes.extra?.reasoning ?? '', '', false, false, chat.indexOf(mes), {}, true); let bookmarkLink = mes?.extra?.bookmark_link ?? ''; let params = { @@ -3205,7 +3210,7 @@ class StreamingProcessor { if (this.reasoning) { chat[messageId]['extra']['reasoning'] = this.reasoning; if (this.messageReasoningDom instanceof HTMLElement) { - const formattedReasoning = messageFormatting(this.reasoning, '', false, false, -1); + const formattedReasoning = messageFormatting(this.reasoning, '', false, false, messageId, {}, true); this.messageReasoningDom.innerHTML = formattedReasoning; } } @@ -3232,6 +3237,8 @@ class StreamingProcessor { chat[messageId].is_system, chat[messageId].is_user, messageId, + {}, + false, ); if (this.messageTextDom instanceof HTMLElement) { this.messageTextDom.innerHTML = formattedText; @@ -3383,7 +3390,7 @@ class StreamingProcessor { if (logprobs) { this.messageLogprobs.push(...(Array.isArray(logprobs) ? logprobs : [logprobs])); } - this.reasoning = state?.reasoning ?? ''; + this.reasoning = getRegexedString(state?.reasoning ?? '', regex_placement.REASONING); await eventSource.emit(event_types.STREAM_TOKEN_RECEIVED, text); await sw.tick(() => this.onProgressStreaming(this.messageId, this.continueMessage + text)); } @@ -3850,14 +3857,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro coreChat.pop(); } - const reasoning = new PromptReasoning(); - for (let i = coreChat.length - 1; i >= 0; i--) { - if (reasoning.isLimitReached()) { - break; - } - coreChat[i] = { ...coreChat[i], mes: reasoning.addToMessage(coreChat[i].mes, coreChat[i].extra?.reasoning) }; - } - coreChat = await Promise.all(coreChat.map(async (chatItem, index) => { let message = chatItem.mes; let regexType = chatItem.is_user ? regex_placement.USER_INPUT : regex_placement.AI_OUTPUT; @@ -3877,6 +3876,25 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro }; })); + const reasoning = new PromptReasoning(); + for (let i = coreChat.length - 1; i >= 0; i--) { + if (reasoning.isLimitReached()) { + break; + } + const depth = coreChat.length - i - 1; + coreChat[i] = { + mes: reasoning.addToMessage( + coreChat[i].mes, + getRegexedString( + coreChat[i].extra?.reasoning, + regex_placement.REASONING, + { isPrompt: true, depth: depth }, + ), + ), + ...coreChat[i], + }; + } + // Determine token limit let this_max_context = getMaxContextSize(); @@ -4785,6 +4803,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro const swipes = extractMultiSwipes(data, type); messageChunk = cleanUpMessage(getMessage, isImpersonate, isContinue, false); + reasoning = getRegexedString(reasoning, regex_placement.REASONING); if (isContinue) { getMessage = continue_mag + getMessage; @@ -7177,9 +7196,11 @@ function messageEditAuto(div) { mes.is_system, mes.is_user, this_edit_mes_id, + {}, + false, )); mesBlock.find('.mes_bias').empty(); - mesBlock.find('.mes_bias').append(messageFormatting(bias, '', false, false, -1)); + mesBlock.find('.mes_bias').append(messageFormatting(bias, '', false, false, -1, {}, false)); saveChatDebounced(); } @@ -7201,10 +7222,12 @@ async function messageEditDone(div) { mes.is_system, mes.is_user, this_edit_mes_id, + {}, + false, ), ); mesBlock.find('.mes_bias').empty(); - mesBlock.find('.mes_bias').append(messageFormatting(bias, '', false, false, -1)); + mesBlock.find('.mes_bias').append(messageFormatting(bias, '', false, false, -1, {}, false)); appendMediaToMessage(mes, div.closest('.mes')); addCopyToCodeBlocks(div.closest('.mes')); @@ -10841,6 +10864,8 @@ jQuery(async function () { chat[this_edit_mes_id].is_system, chat[this_edit_mes_id].is_user, this_edit_mes_id, + {}, + false, )); appendMediaToMessage(chat[this_edit_mes_id], $(this).closest('.mes')); addCopyToCodeBlocks($(this).closest('.mes')); diff --git a/public/scripts/extensions/regex/editor.html b/public/scripts/extensions/regex/editor.html index 9e699a622..8cfe9e008 100644 --- a/public/scripts/extensions/regex/editor.html +++ b/public/scripts/extensions/regex/editor.html @@ -94,6 +94,12 @@ World Info +
+ +
diff --git a/public/scripts/extensions/regex/engine.js b/public/scripts/extensions/regex/engine.js index 8c28d01f3..08de07d6a 100644 --- a/public/scripts/extensions/regex/engine.js +++ b/public/scripts/extensions/regex/engine.js @@ -20,6 +20,7 @@ const regex_placement = { SLASH_COMMAND: 3, // 4 - sendAs (legacy) WORLD_INFO: 5, + REASONING: 6, }; export const substitute_find_regex = { From 0a413d63aa2630b755a6ce8df1411110e402eb4d Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:11:31 +0200 Subject: [PATCH 2/5] Add reasoning regex on edit --- public/scripts/reasoning.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/scripts/reasoning.js b/public/scripts/reasoning.js index c9b0efc3b..0bf7bee90 100644 --- a/public/scripts/reasoning.js +++ b/public/scripts/reasoning.js @@ -1,4 +1,5 @@ import { chat, closeMessageEditor, saveChatConditional, saveSettingsDebounced, substituteParams, updateMessageBlock } from '../script.js'; +import { getRegexedString, regex_placement } from './extensions/regex/engine.js'; import { t } from './i18n.js'; import { MacrosParser } from './macros.js'; import { Popup } from './popup.js'; @@ -224,7 +225,7 @@ function setReasoningEventHandlers(){ } const textarea = messageBlock.find('.reasoning_edit_textarea'); - const reasoning = String(textarea.val()); + const reasoning = getRegexedString(String(textarea.val()), regex_placement.REASONING, { isEdit: true }); message.extra.reasoning = reasoning; await saveChatConditional(); updateMessageBlock(messageId, message); From 0fb9884ab8bcca2b43e2f2617117b197f5cda3f2 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 27 Jan 2025 23:59:25 +0200 Subject: [PATCH 3/5] Skill issue --- public/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 09d7a921b..29abebbce 100644 --- a/public/script.js +++ b/public/script.js @@ -3883,6 +3883,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro } const depth = coreChat.length - i - 1; coreChat[i] = { + ...coreChat[i], mes: reasoning.addToMessage( coreChat[i].mes, getRegexedString( @@ -3891,7 +3892,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro { isPrompt: true, depth: depth }, ), ), - ...coreChat[i], }; } From d616dfef38a801114c0666ad3171ea8838777558 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:03:38 +0200 Subject: [PATCH 4/5] Prevent log warning spam --- public/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index 29abebbce..ab94faf21 100644 --- a/public/script.js +++ b/public/script.js @@ -3887,7 +3887,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro mes: reasoning.addToMessage( coreChat[i].mes, getRegexedString( - coreChat[i].extra?.reasoning, + String(coreChat[i].extra?.reasoning ?? ''), regex_placement.REASONING, { isPrompt: true, depth: depth }, ), From a6a7810be2cb3bb7db4dca5a16fdac65e518e97d Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:39:32 +0200 Subject: [PATCH 5/5] Regex: fix "Alter Outgoing Prompt" applying when unchecked (#3380) * Regex: rework ephemerality options. * Fix ephemeral regex being executed when unwanted * Revert to old code style --- public/scripts/extensions/regex/engine.js | 2 +- public/scripts/extensions/regex/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/extensions/regex/engine.js b/public/scripts/extensions/regex/engine.js index 08de07d6a..f6e22d249 100644 --- a/public/scripts/extensions/regex/engine.js +++ b/public/scripts/extensions/regex/engine.js @@ -95,7 +95,7 @@ function getRegexedString(rawString, placement, { characterOverride, isMarkdown, // Script applies to Generate and input is Generate (script.promptOnly && isPrompt) || // Script applies to all cases when neither "only"s are true, but there's no need to do it when `isMarkdown`, the as source (chat history) should already be changed beforehand - (!script.markdownOnly && !script.promptOnly && !isMarkdown) + (!script.markdownOnly && !script.promptOnly && !isMarkdown && !isPrompt) ) { if (isEdit && !script.runOnEdit) { console.debug(`getRegexedString: Skipping script ${script.scriptName} because it does not run on edit`); diff --git a/public/scripts/extensions/regex/index.js b/public/scripts/extensions/regex/index.js index 73538e4ed..8ac6ae6d6 100644 --- a/public/scripts/extensions/regex/index.js +++ b/public/scripts/extensions/regex/index.js @@ -18,7 +18,7 @@ import { t } from '../../i18n.js'; * @property {string} replaceString - The replace string * @property {string[]} trimStrings - The trim strings * @property {string?} findRegex - The find regex - * @property {string?} substituteRegex - The substitute regex + * @property {number?} substituteRegex - The substitute regex */ /**