Adjust itemized prompts on message move/delete (#5000) * Adjust itemized prompts on message move/delete * Sort itemized prompts on swap * Remove itemized prompt on regeneration
Signed| @@ -272,7 +272,7 @@ import { extractReasoningFromData, extractReasoningSignatureFromData, initReason | ||
| 272 | 272 | import { accountStorage } from './scripts/util/AccountStorage.js'; |
| 273 | 273 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard, getPermanentAssistantAvatar } from './scripts/welcome-screen.js'; |
| 274 | 274 | import { initDataMaid } from './scripts/data-maid.js'; |
| 275 | 275 | import { clearItemizedPrompts, deleteItemizedPromptForMessage, deleteItemizedPrompts, findItemizedPromptSet, initItemizedPrompts, itemizedParams, itemizedPrompts, loadItemizedPrompts, promptItemize, replaceItemizedPromptText, saveItemizedPrompts, swapItemizedPrompts } from './scripts/itemized-prompts.js'; |
| 276 | 276 | import { getSystemMessageByType, initSystemMessages, SAFETY_CHAT, sendSystemMessage, system_message_types, system_messages } from './scripts/system-messages.js'; |
| 277 | 277 | import { event_types, eventSource } from './scripts/events.js'; |
| 278 | 278 | import { initAccessibility } from './scripts/a11y.js'; |
| @@ -1546,6 +1546,7 @@ export async function clearChat() { | ||
| 1546 | 1546 | } |
| 1547 | 1547 | |
| 1548 | 1548 | export async function deleteLastMessage() { |
| 1549 | + deleteItemizedPromptForMessage(chat.length - 1); | |
| 1549 | 1550 | chat.length = chat.length - 1; |
| 1550 | 1551 | chatElement.children('.mes').last().remove(); |
| 1551 | 1552 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| @@ -1601,6 +1602,7 @@ export async function deleteMessage(id, swipeDeletionIndex = undefined, askConfi | ||
| 1601 | 1602 | chat_metadata.tainted = true; |
| 1602 | 1603 | |
| 1603 | 1604 | const startIndex = [0, minId].includes(id) ? id : null; |
| 1605 | + deleteItemizedPromptForMessage(id); | |
| 1604 | 1606 | updateViewMessageIds(startIndex); |
| 1605 | 1607 | saveChatDebounced(); |
| 1606 | 1608 | |
| @@ -4230,6 +4232,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | ||
| 4230 | 4232 | //do nothing? why does this check exist? |
| 4231 | 4233 | } |
| 4232 | 4234 | else if (type !== 'quiet' && type !== 'swipe' && !isImpersonate && !dryRun && chat.length) { |
| 4235 | + deleteItemizedPromptForMessage(chat.length - 1); | |
| 4233 | 4236 | chat.length = chat.length - 1; |
| 4234 | 4237 | await removeLastMessage(); |
| 4235 | 4238 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| @@ -8142,6 +8145,7 @@ async function messageEditMove(sourceId, targetId) { | ||
| 8142 | 8145 | this_edit_mes_id = targetId; |
| 8143 | 8146 | } |
| 8144 | 8147 | |
| 8148 | + swapItemizedPrompts(sourceId, targetId); | |
| 8145 | 8149 | updateViewMessageIds(); |
| 8146 | 8150 | refreshSwipeButtons(); |
| 8147 | 8151 | await saveChatConditional(); |
| @@ -11450,6 +11454,9 @@ jQuery(async function () { | ||
| 11450 | 11454 | }); |
| 11451 | 11455 | |
| 11452 | 11456 | if (this_del_mes >= 0) { |
| 11457 | + for (let i = (chat.length - 1); i >= this_del_mes; i--) { | |
| 11458 | + deleteItemizedPromptForMessage(i); | |
| 11459 | + } | |
| 11453 | 11460 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); |
| 11454 | 11461 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).remove(); |
| 11455 | 11462 | chat.length = this_del_mes; |
| @@ -222,6 +222,7 @@ export async function itemizedParams(itemizedPrompts, thisPromptSet, incomingMes | ||
| 222 | 222 | |
| 223 | 223 | export function findItemizedPromptSet(itemizedPrompts, incomingMesId) { |
| 224 | 224 | let thisPromptSet = undefined; |
| 225 | + priorPromptArrayItemForRawPromptDisplay = -1; | |
| 225 | 226 | |
| 226 | 227 | for (let i = 0; i < itemizedPrompts.length; i++) { |
| 227 | 228 | console.log(`looking for ${incomingMesId} vs ${itemizedPrompts[i].mesId}`); |
| @@ -262,7 +263,7 @@ export async function promptItemize(itemizedPrompts, requestedMesId) { | ||
| 262 | 263 | |
| 263 | 264 | /** @type {HTMLElement} */ |
| 264 | 265 | const diffPrevPrompt = popup.dlg.querySelector('#diffPrevPrompt'); |
| 265 | 266 | if (priorPromptArrayItemForRawPromptDisplay >= 0) { |
| 266 | 267 | diffPrevPrompt.style.display = ''; |
| 267 | 268 | diffPrevPrompt.addEventListener('click', function () { |
| 268 | 269 | const dmp = new DiffMatchPatch(); |
| @@ -350,3 +351,44 @@ export function initItemizedPrompts() { | ||
| 350 | 351 | await deleteItemizedPrompts(name); |
| 351 | 352 | }); |
| 352 | 353 | } |
| 354 | + | |
| 355 | +/** | |
| 356 | + * Swaps the itemized prompts between two messages. Useful when moving messages around in the chat. | |
| 357 | + * @param {number} sourceMessageId Source message ID | |
| 358 | + * @param {number} targetMessageId Target message ID | |
| 359 | + */ | |
| 360 | +export function swapItemizedPrompts(sourceMessageId, targetMessageId) { | |
| 361 | + if (!Array.isArray(itemizedPrompts)) { | |
| 362 | + return; | |
| 363 | + } | |
| 364 | + | |
| 365 | + const sourcePrompts = itemizedPrompts.filter(x => x.mesId === sourceMessageId); | |
| 366 | + const targetPrompts = itemizedPrompts.filter(x => x.mesId === targetMessageId); | |
| 367 | + | |
| 368 | + sourcePrompts.forEach(prompt => { | |
| 369 | + prompt.mesId = targetMessageId; | |
| 370 | + }); | |
| 371 | + | |
| 372 | + targetPrompts.forEach(prompt => { | |
| 373 | + prompt.mesId = sourceMessageId; | |
| 374 | + }); | |
| 375 | + | |
| 376 | + itemizedPrompts.sort((a, b) => a.mesId - b.mesId); | |
| 377 | +} | |
| 378 | + | |
| 379 | +/** | |
| 380 | + * Deletes the itemized prompt for a specific message. | |
| 381 | + * Shifts down other itemized prompts as necessary. | |
| 382 | + * @param {number} messageId Message ID to delete itemized prompt for | |
| 383 | + */ | |
| 384 | +export function deleteItemizedPromptForMessage(messageId) { | |
| 385 | + if (!Array.isArray(itemizedPrompts)) { | |
| 386 | + return; | |
| 387 | + } | |
| 388 | + | |
| 389 | + itemizedPrompts = itemizedPrompts.filter(x => x.mesId !== messageId); | |
| 390 | + | |
| 391 | + for (const prompt of itemizedPrompts.filter(x => x.mesId > messageId)) { | |
| 392 | + prompt.mesId -= 1; | |
| 393 | + } | |
| 394 | +} | |