Functional reasoning edit

17d4175b47bb274048f2503ecb8e423836265308

Cohee <18619528+Cohee1207@users.noreply.github.com>

3 files changed, +81 -6Ignore whitespace
public/script.js+21 -6
@@ -5686,7 +5686,7 @@ function parseAndSaveLogprobs(data, continueFrom) {
56865686 * @param {object} data Response data
56875687 * @returns {string} Extracted message
56885688 */
56895689function extractMessageFromData(data) {
56905690 if (typeof data === 'string') {
56915691 return data;
56925692 }
@@ -8042,9 +8042,23 @@ function updateEditArrowClasses() {
80428042 }
80438043}
80448044
8045-export function closeMessageEditor() {
8045+/**
8046- if (this_edit_mes_id) {
8046+ * Closes the message editor.
8047- $(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_cancel`).click();
8047+ * @param {'message'|'reasoning'|'all'} what What to close. Default is 'all'.
8048+ */
8049+export function closeMessageEditor(what = 'all') {
8050+ if (what === 'message' || what === 'all') {
8051+ if (this_edit_mes_id) {
8052+ $(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_cancel`).click();
8053+ }
8054+ }
8055+ if (what === 'reasoning' || what === 'all') {
8056+ document.querySelectorAll('.reasoning_edit_textarea').forEach((el) => {
8057+ const cancelButton = el.closest('.mes')?.querySelector('.mes_reasoning_edit_cancel');
8058+ if (cancelButton instanceof HTMLElement) {
8059+ cancelButton.click();
8060+ }
8061+ });
80488062 }
80498063}
80508064
@@ -11274,14 +11288,15 @@ jQuery(async function () {
1127411288
1127511289 $(document).keyup(function (e) {
1127611290 if (e.key === 'Escape') {
1127711291 const isEditVisible = $('#curEditTextarea').is(':visible') || $('.reasoning_edit_textarea').length > 0;
1127811292 if (isEditVisible && power_user.auto_save_msg_edits === false) {
1127911293 closeMessageEditor('all');
1128011294 $('#send_textarea').focus();
1128111295 return;
1128211296 }
1128311297 if (isEditVisible && power_user.auto_save_msg_edits === true) {
1128411298 $(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_done`).click();
11299+ closeMessageEditor('reasoning');
1128511300 $('#send_textarea').focus();
1128611301 return;
1128711302 }
public/scripts/chats.js+50 -0
@@ -1650,11 +1650,61 @@ jQuery(function () {
16501650 }
16511651
16521652 const reasoning = message?.extra?.reasoning;
1653+ const chatElement = document.getElementById('chat');
16531654 const textarea = document.createElement('textarea');
16541655 const reasoningBlock = messageBlock.find('.mes_reasoning');
16551656 textarea.classList.add('reasoning_edit_textarea');
16561657 textarea.value = reasoning === PromptReasoning.REASONING_PLACEHOLDER ? '' : reasoning;
16571658 $(textarea).insertBefore(reasoningBlock);
1659+
1660+ if (!CSS.supports('field-sizing', 'content')) {
1661+ const resetHeight = function () {
1662+ const scrollTop = chatElement.scrollTop;
1663+ textarea.style.height = '0px';
1664+ textarea.style.height = `${textarea.scrollHeight}px`;
1665+ chatElement.scrollTop = scrollTop;
1666+ };
1667+
1668+ textarea.addEventListener('input', resetHeight);
1669+ resetHeight();
1670+ }
1671+
1672+ textarea.focus();
1673+ textarea.setSelectionRange(textarea.value.length, textarea.value.length);
1674+
1675+ const textareaRect = textarea.getBoundingClientRect();
1676+ const chatRect = chatElement.getBoundingClientRect();
1677+
1678+ // Scroll if textarea bottom is below visible area
1679+ if (textareaRect.bottom > chatRect.bottom) {
1680+ const scrollOffset = textareaRect.bottom - chatRect.bottom;
1681+ chatElement.scrollTop += scrollOffset;
1682+ }
1683+ });
1684+
1685+ $(document).on('click', '.mes_reasoning_edit_done', async function (e) {
1686+ e.stopPropagation();
1687+ e.preventDefault();
1688+ const { message, messageId, messageBlock } = getMessageFromJquery(this);
1689+ if (!message?.extra) {
1690+ return;
1691+ }
1692+
1693+ const textarea = messageBlock.find('.reasoning_edit_textarea');
1694+ const reasoning = String(textarea.val());
1695+ message.extra.reasoning = reasoning;
1696+ await saveChatConditional();
1697+ updateMessageBlock(messageId, message);
1698+ textarea.remove();
1699+ });
1700+
1701+ $(document).on('click', '.mes_reasoning_edit_cancel', function (e) {
1702+ e.stopPropagation();
1703+ e.preventDefault();
1704+
1705+ const { messageBlock } = getMessageFromJquery(this);
1706+ const textarea = messageBlock.find('.reasoning_edit_textarea');
1707+ textarea.remove();
16581708 });
16591709
16601710 $(document).on('click', '.mes_edit_add_reasoning', async function () {
public/style.css+10 -0
@@ -356,6 +356,12 @@ input[type='checkbox']:focus-visible {
356356 margin: 2px;
357357}
358358
359+@supports not selector(:has(*)) {
360+ .mes_reasoning_details {
361+ display: none !important;
362+ }
363+}
364+
359365.mes_bias:empty,
360366.mes_reasoning:empty,
361367.mes_reasoning_details:has(.mes_reasoning:empty),
@@ -1089,6 +1095,10 @@ body .panelControlBar {
10891095 /*only affects bubblechat to make it sit nicely at the bottom*/
10901096}
10911097
1098+.last_mes:has(.mes_text:empty):has(.mes_reasoning_details[open]) .mes_reasoning:not(:empty) {
1099+ margin-bottom: 30px;
1100+}
1101+
10921102.last_mes .mes_reasoning,
10931103.last_mes .mes_text {
10941104 padding-right: 30px;