Fix continue duplicating reasoning block

This commit is contained in:
Cohee
2025-03-04 00:42:50 +02:00
parent 7d568dd4e0
commit 7be6e0d5af
2 changed files with 57 additions and 8 deletions

View File

@@ -3135,8 +3135,9 @@ class StreamingProcessor {
* @param {boolean} forceName2 If true, force the use of name2 * @param {boolean} forceName2 If true, force the use of name2
* @param {Date} timeStarted Date when generation was started * @param {Date} timeStarted Date when generation was started
* @param {string} continueMessage Previous message if the type is 'continue' * @param {string} continueMessage Previous message if the type is 'continue'
* @param {PromptReasoning} promptReasoning Prompt reasoning instance
*/ */
constructor(type, forceName2, timeStarted, continueMessage) { constructor(type, forceName2, timeStarted, continueMessage, promptReasoning) {
this.result = ''; this.result = '';
this.messageId = -1; this.messageId = -1;
/** @type {HTMLElement} */ /** @type {HTMLElement} */
@@ -3164,6 +3165,8 @@ class StreamingProcessor {
this.toolCalls = []; this.toolCalls = [];
// Initialize reasoning in its own handler // Initialize reasoning in its own handler
this.reasoningHandler = new ReasoningHandler(timeStarted); this.reasoningHandler = new ReasoningHandler(timeStarted);
/** @type {PromptReasoning} */
this.promptReasoning = promptReasoning;
} }
#checkDomElements(messageId) { #checkDomElements(messageId) {
@@ -3192,6 +3195,10 @@ class StreamingProcessor {
} }
async onStartStreaming(text) { async onStartStreaming(text) {
if (this.type === 'continue' && this.promptReasoning.prefixReasoning) {
this.reasoningHandler.initContinue(this.promptReasoning);
}
let messageId = -1; let messageId = -1;
if (this.type == 'impersonate') { if (this.type == 'impersonate') {
@@ -3882,13 +3889,13 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
}; };
})); }));
const reasoning = new PromptReasoning(); const promptReasoning = new PromptReasoning();
for (let i = coreChat.length - 1; i >= 0; i--) { for (let i = coreChat.length - 1; i >= 0; i--) {
const depth = coreChat.length - i - 1; const depth = coreChat.length - i - 1;
const isPrefix = isContinue && i === coreChat.length - 1; const isPrefix = isContinue && i === coreChat.length - 1;
coreChat[i] = { coreChat[i] = {
...coreChat[i], ...coreChat[i],
mes: reasoning.addToMessage( mes: promptReasoning.addToMessage(
coreChat[i].mes, coreChat[i].mes,
getRegexedString( getRegexedString(
String(coreChat[i].extra?.reasoning ?? ''), String(coreChat[i].extra?.reasoning ?? ''),
@@ -3896,9 +3903,10 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
{ isPrompt: true, depth: depth }, { isPrompt: true, depth: depth },
), ),
isPrefix, isPrefix,
coreChat[i].extra?.reasoning_duration,
), ),
}; };
if (reasoning.isLimitReached()) { if (promptReasoning.isLimitReached()) {
break; break;
} }
} }
@@ -4723,7 +4731,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
console.debug(`pushed prompt bits to itemizedPrompts array. Length is now: ${itemizedPrompts.length}`); console.debug(`pushed prompt bits to itemizedPrompts array. Length is now: ${itemizedPrompts.length}`);
if (isStreamingEnabled() && type !== 'quiet') { if (isStreamingEnabled() && type !== 'quiet') {
streamingProcessor = new StreamingProcessor(type, force_name2, generation_started, continue_mag); continue_mag = promptReasoning.removePrefix(continue_mag);
streamingProcessor = new StreamingProcessor(type, force_name2, generation_started, continue_mag, promptReasoning);
if (isContinue) { if (isContinue) {
// Save reply does add cycle text to the prompt, so it's not needed here // Save reply does add cycle text to the prompt, so it's not needed here
streamingProcessor.firstMessageText = ''; streamingProcessor.firstMessageText = '';
@@ -4824,6 +4833,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
} }
if (isContinue) { if (isContinue) {
continue_mag = promptReasoning.removePrefix(continue_mag);
getMessage = continue_mag + getMessage; getMessage = continue_mag + getMessage;
} }

View File

@@ -188,6 +188,17 @@ export class ReasoningHandler {
this.messageReasoningHeaderDom = null; this.messageReasoningHeaderDom = null;
} }
/**
* Sets the reasoning state when continuing a prompt.
* @param {PromptReasoning} promptReasoning Prompt reasoning object
*/
initContinue(promptReasoning) {
this.reasoning = promptReasoning.prefixReasoning;
this.state = ReasoningState.Done;
this.startTime = this.initialTime;
this.endTime = promptReasoning.prefixDuration ? new Date(this.initialTime.getTime() + promptReasoning.prefixDuration) : null;
}
/** /**
* Initializes the reasoning handler for a specific message. * Initializes the reasoning handler for a specific message.
* *
@@ -514,6 +525,9 @@ export class PromptReasoning {
constructor() { constructor() {
this.counter = 0; this.counter = 0;
this.prefixLength = -1;
this.prefixReasoning = '';
this.prefixDuration = null;
} }
/** /**
@@ -533,9 +547,10 @@ export class PromptReasoning {
* @param {string} content Message content * @param {string} content Message content
* @param {string} reasoning Message reasoning * @param {string} reasoning Message reasoning
* @param {boolean} isPrefix Whether this is the last message prefix * @param {boolean} isPrefix Whether this is the last message prefix
* @param {number?} duration Duration of the reasoning
* @returns {string} Message content with reasoning * @returns {string} Message content with reasoning
*/ */
addToMessage(content, reasoning, isPrefix) { addToMessage(content, reasoning, isPrefix, duration) {
// Disabled or reached limit of additions // Disabled or reached limit of additions
if (!isPrefix && (!power_user.reasoning.add_to_prompts || this.counter >= power_user.reasoning.max_additions)) { if (!isPrefix && (!power_user.reasoning.add_to_prompts || this.counter >= power_user.reasoning.max_additions)) {
return content; return content;
@@ -556,11 +571,35 @@ export class PromptReasoning {
// Combine parts with reasoning only // Combine parts with reasoning only
if (isPrefix && !content) { if (isPrefix && !content) {
return `${prefix}${reasoning}`; const formattedReasoning = `${prefix}${reasoning}`;
if (isPrefix) {
this.prefixReasoning = reasoning;
this.prefixLength = formattedReasoning.length;
this.prefixDuration = duration;
}
return formattedReasoning;
} }
// Combine parts with reasoning and content // Combine parts with reasoning and content
return `${prefix}${reasoning}${suffix}${separator}${content}`; const formattedReasoning = `${prefix}${reasoning}${suffix}${separator}`;
if (isPrefix) {
this.prefixReasoning = reasoning;
this.prefixLength = formattedReasoning.length;
this.prefixDuration = duration;
}
return `${formattedReasoning}${content}`;
}
/**
* Removes the reasoning prefix from the content.
* @param {string} content Content with the reasoning prefix
* @returns {string} Content without the reasoning prefix
*/
removePrefix(content) {
if (this.prefixLength > 0) {
return content.slice(this.prefixLength);
}
return content;
} }
} }