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 | import { accountStorage } from './scripts/util/AccountStorage.js'; | 272 | import { accountStorage } from './scripts/util/AccountStorage.js'; |
| 273 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard, getPermanentAssistantAvatar } from './scripts/welcome-screen.js'; | 273 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard, getPermanentAssistantAvatar } from './scripts/welcome-screen.js'; |
| 274 | import { initDataMaid } from './scripts/data-maid.js'; | 274 | import { initDataMaid } from './scripts/data-maid.js'; |
| 275 | import { clearItemizedPrompts, deleteItemizedPrompts, findItemizedPromptSet, initItemizedPrompts, itemizedParams, itemizedPrompts, loadItemizedPrompts, promptItemize, replaceItemizedPromptText, saveItemizedPrompts } from './scripts/itemized-prompts.js'; | 275 | import { clearItemizedPrompts, deleteItemizedPromptForMessage, deleteItemizedPrompts, findItemizedPromptSet, initItemizedPrompts, itemizedParams, itemizedPrompts, loadItemizedPrompts, promptItemize, replaceItemizedPromptText, saveItemizedPrompts, swapItemizedPrompts } from './scripts/itemized-prompts.js'; |
| 276 | import { getSystemMessageByType, initSystemMessages, SAFETY_CHAT, sendSystemMessage, system_message_types, system_messages } from './scripts/system-messages.js'; | 276 | import { getSystemMessageByType, initSystemMessages, SAFETY_CHAT, sendSystemMessage, system_message_types, system_messages } from './scripts/system-messages.js'; |
| 277 | import { event_types, eventSource } from './scripts/events.js'; | 277 | import { event_types, eventSource } from './scripts/events.js'; |
| 278 | import { initAccessibility } from './scripts/a11y.js'; | 278 | import { initAccessibility } from './scripts/a11y.js'; |
| @@ -1546,6 +1546,7 @@ export async function clearChat() { | |||
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | export async function deleteLastMessage() { | 1548 | export async function deleteLastMessage() { |
| 1549 | deleteItemizedPromptForMessage(chat.length - 1); | ||
| 1549 | chat.length = chat.length - 1; | 1550 | chat.length = chat.length - 1; |
| 1550 | chatElement.children('.mes').last().remove(); | 1551 | chatElement.children('.mes').last().remove(); |
| 1551 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); | 1552 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| @@ -1601,6 +1602,7 @@ export async function deleteMessage(id, swipeDeletionIndex = undefined, askConfi | |||
| 1601 | chat_metadata.tainted = true; | 1602 | chat_metadata.tainted = true; |
| 1602 | 1603 | ||
| 1603 | const startIndex = [0, minId].includes(id) ? id : null; | 1604 | const startIndex = [0, minId].includes(id) ? id : null; |
| 1605 | deleteItemizedPromptForMessage(id); | ||
| 1604 | updateViewMessageIds(startIndex); | 1606 | updateViewMessageIds(startIndex); |
| 1605 | saveChatDebounced(); | 1607 | saveChatDebounced(); |
| 1606 | 1608 | ||
| @@ -4230,6 +4232,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4230 | //do nothing? why does this check exist? | 4232 | //do nothing? why does this check exist? |
| 4231 | } | 4233 | } |
| 4232 | else if (type !== 'quiet' && type !== 'swipe' && !isImpersonate && !dryRun && chat.length) { | 4234 | else if (type !== 'quiet' && type !== 'swipe' && !isImpersonate && !dryRun && chat.length) { |
| 4235 | deleteItemizedPromptForMessage(chat.length - 1); | ||
| 4233 | chat.length = chat.length - 1; | 4236 | chat.length = chat.length - 1; |
| 4234 | await removeLastMessage(); | 4237 | await removeLastMessage(); |
| 4235 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); | 4238 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| @@ -8142,6 +8145,7 @@ async function messageEditMove(sourceId, targetId) { | |||
| 8142 | this_edit_mes_id = targetId; | 8145 | this_edit_mes_id = targetId; |
| 8143 | } | 8146 | } |
| 8144 | 8147 | ||
| 8148 | swapItemizedPrompts(sourceId, targetId); | ||
| 8145 | updateViewMessageIds(); | 8149 | updateViewMessageIds(); |
| 8146 | refreshSwipeButtons(); | 8150 | refreshSwipeButtons(); |
| 8147 | await saveChatConditional(); | 8151 | await saveChatConditional(); |
| @@ -11450,6 +11454,9 @@ jQuery(async function () { | |||
| 11450 | }); | 11454 | }); |
| 11451 | 11455 | ||
| 11452 | if (this_del_mes >= 0) { | 11456 | if (this_del_mes >= 0) { |
| 11457 | for (let i = (chat.length - 1); i >= this_del_mes; i--) { | ||
| 11458 | deleteItemizedPromptForMessage(i); | ||
| 11459 | } | ||
| 11453 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); | 11460 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); |
| 11454 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).remove(); | 11461 | chatElement.find(`.mes[mesid="${this_del_mes}"]`).remove(); |
| 11455 | chat.length = this_del_mes; | 11462 | chat.length = this_del_mes; |
| @@ -222,6 +222,7 @@ export async function itemizedParams(itemizedPrompts, thisPromptSet, incomingMes | |||
| 222 | 222 | ||
| 223 | export function findItemizedPromptSet(itemizedPrompts, incomingMesId) { | 223 | export function findItemizedPromptSet(itemizedPrompts, incomingMesId) { |
| 224 | let thisPromptSet = undefined; | 224 | let thisPromptSet = undefined; |
| 225 | priorPromptArrayItemForRawPromptDisplay = -1; | ||
| 225 | 226 | ||
| 226 | for (let i = 0; i < itemizedPrompts.length; i++) { | 227 | for (let i = 0; i < itemizedPrompts.length; i++) { |
| 227 | console.log(`looking for ${incomingMesId} vs ${itemizedPrompts[i].mesId}`); | 228 | console.log(`looking for ${incomingMesId} vs ${itemizedPrompts[i].mesId}`); |
| @@ -262,7 +263,7 @@ export async function promptItemize(itemizedPrompts, requestedMesId) { | |||
| 262 | 263 | ||
| 263 | /** @type {HTMLElement} */ | 264 | /** @type {HTMLElement} */ |
| 264 | const diffPrevPrompt = popup.dlg.querySelector('#diffPrevPrompt'); | 265 | const diffPrevPrompt = popup.dlg.querySelector('#diffPrevPrompt'); |
| 265 | if (priorPromptArrayItemForRawPromptDisplay) { | 266 | if (priorPromptArrayItemForRawPromptDisplay >= 0) { |
| 266 | diffPrevPrompt.style.display = ''; | 267 | diffPrevPrompt.style.display = ''; |
| 267 | diffPrevPrompt.addEventListener('click', function () { | 268 | diffPrevPrompt.addEventListener('click', function () { |
| 268 | const dmp = new DiffMatchPatch(); | 269 | const dmp = new DiffMatchPatch(); |
| @@ -350,3 +351,44 @@ export function initItemizedPrompts() { | |||
| 350 | await deleteItemizedPrompts(name); | 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 | } | ||