mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Move reasoning-specific code into its own module
This commit is contained in:
@ -238,7 +238,7 @@ import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_set
|
|||||||
import { hideLoader, showLoader } from './scripts/loader.js';
|
import { hideLoader, showLoader } from './scripts/loader.js';
|
||||||
import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
|
import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
|
||||||
import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels, loadGenericModels } from './scripts/textgen-models.js';
|
import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels, loadGenericModels } from './scripts/textgen-models.js';
|
||||||
import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat, PromptReasoning } from './scripts/chats.js';
|
import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js';
|
||||||
import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
|
import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
|
||||||
import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
|
import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
|
||||||
import { currentUser, setUserControls } from './scripts/user.js';
|
import { currentUser, setUserControls } from './scripts/user.js';
|
||||||
@ -267,6 +267,7 @@ import { initSettingsSearch } from './scripts/setting-search.js';
|
|||||||
import { initBulkEdit } from './scripts/bulk-edit.js';
|
import { initBulkEdit } from './scripts/bulk-edit.js';
|
||||||
import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
|
import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
|
||||||
import { getContext } from './scripts/st-context.js';
|
import { getContext } from './scripts/st-context.js';
|
||||||
|
import { initReasoning, PromptReasoning } from './scripts/reasoning.js';
|
||||||
|
|
||||||
// API OBJECT FOR EXTERNAL WIRING
|
// API OBJECT FOR EXTERNAL WIRING
|
||||||
globalThis.SillyTavern = {
|
globalThis.SillyTavern = {
|
||||||
@ -982,6 +983,7 @@ async function firstLoadInit() {
|
|||||||
initServerHistory();
|
initServerHistory();
|
||||||
initSettingsSearch();
|
initSettingsSearch();
|
||||||
initBulkEdit();
|
initBulkEdit();
|
||||||
|
initReasoning();
|
||||||
await initScrapers();
|
await initScrapers();
|
||||||
doDailyExtensionUpdatesCheck();
|
doDailyExtensionUpdatesCheck();
|
||||||
await hideLoader();
|
await hideLoader();
|
||||||
|
@ -23,9 +23,6 @@ import {
|
|||||||
neutralCharacterName,
|
neutralCharacterName,
|
||||||
updateChatMetadata,
|
updateChatMetadata,
|
||||||
system_message_types,
|
system_message_types,
|
||||||
updateMessageBlock,
|
|
||||||
closeMessageEditor,
|
|
||||||
substituteParams,
|
|
||||||
} from '../script.js';
|
} from '../script.js';
|
||||||
import { selected_group } from './group-chats.js';
|
import { selected_group } from './group-chats.js';
|
||||||
import { power_user } from './power-user.js';
|
import { power_user } from './power-user.js';
|
||||||
@ -40,7 +37,6 @@ import {
|
|||||||
saveBase64AsFile,
|
saveBase64AsFile,
|
||||||
extractTextFromOffice,
|
extractTextFromOffice,
|
||||||
download,
|
download,
|
||||||
copyText,
|
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js';
|
import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js';
|
||||||
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||||
@ -1420,72 +1416,7 @@ export function registerFileConverter(mimeType, converter) {
|
|||||||
converters[mimeType] = converter;
|
converters[mimeType] = converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class for adding reasoning to messages.
|
|
||||||
* Keeps track of the number of reasoning additions.
|
|
||||||
*/
|
|
||||||
export class PromptReasoning {
|
|
||||||
static REASONING_PLACEHOLDER = '\u200B';
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the limit of reasoning additions has been reached.
|
|
||||||
* @returns {boolean} True if the limit of reasoning additions has been reached, false otherwise.
|
|
||||||
*/
|
|
||||||
isLimitReached() {
|
|
||||||
if (!power_user.reasoning.add_to_prompts) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.counter >= power_user.reasoning.max_additions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add reasoning to a message according to the power user settings.
|
|
||||||
* @param {string} content Message content
|
|
||||||
* @param {string} reasoning Message reasoning
|
|
||||||
* @returns {string} Message content with reasoning
|
|
||||||
*/
|
|
||||||
addToMessage(content, reasoning) {
|
|
||||||
// Disabled or reached limit of additions
|
|
||||||
if (!power_user.reasoning.add_to_prompts || this.counter >= power_user.reasoning.max_additions) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No reasoning provided or a placeholder
|
|
||||||
if (!reasoning || reasoning === PromptReasoning.REASONING_PLACEHOLDER) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment the counter
|
|
||||||
this.counter++;
|
|
||||||
|
|
||||||
// Substitute macros in variable parts
|
|
||||||
const prefix = substituteParams(power_user.reasoning.prefix || '');
|
|
||||||
const separator = substituteParams(power_user.reasoning.separator || '');
|
|
||||||
const suffix = substituteParams(power_user.reasoning.suffix || '');
|
|
||||||
|
|
||||||
// Combine parts with reasoning and content
|
|
||||||
return `${prefix}${reasoning}${suffix}${separator}${content}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery(function () {
|
jQuery(function () {
|
||||||
/**
|
|
||||||
* Gets a message from a jQuery element.
|
|
||||||
* @param {Element} element
|
|
||||||
* @returns {{messageId: number, message: object, messageBlock: JQuery<HTMLElement>}}
|
|
||||||
*/
|
|
||||||
const getMessageFromJquery = function (element) {
|
|
||||||
const messageBlock = $(element).closest('.mes');
|
|
||||||
const messageId = Number(messageBlock.attr('mesid'));
|
|
||||||
const message = chat[messageId];
|
|
||||||
return { messageId: messageId, message, messageBlock };
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_hide', async function () {
|
$(document).on('click', '.mes_hide', async function () {
|
||||||
const messageBlock = $(this).closest('.mes');
|
const messageBlock = $(this).closest('.mes');
|
||||||
const messageId = Number(messageBlock.attr('mesid'));
|
const messageId = Number(messageBlock.attr('mesid'));
|
||||||
@ -1636,125 +1567,6 @@ jQuery(function () {
|
|||||||
$(document).on('click', '.mes_img_enlarge', enlargeMessageImage);
|
$(document).on('click', '.mes_img_enlarge', enlargeMessageImage);
|
||||||
$(document).on('click', '.mes_img_delete', deleteMessageImage);
|
$(document).on('click', '.mes_img_delete', deleteMessageImage);
|
||||||
|
|
||||||
$(document).on('click', '.mes_reasoning_copy', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_reasoning_edit', function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
const { message, messageBlock } = getMessageFromJquery(this);
|
|
||||||
if (!message?.extra) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reasoning = message?.extra?.reasoning;
|
|
||||||
const chatElement = document.getElementById('chat');
|
|
||||||
const textarea = document.createElement('textarea');
|
|
||||||
const reasoningBlock = messageBlock.find('.mes_reasoning');
|
|
||||||
textarea.classList.add('reasoning_edit_textarea');
|
|
||||||
textarea.value = reasoning === PromptReasoning.REASONING_PLACEHOLDER ? '' : reasoning;
|
|
||||||
$(textarea).insertBefore(reasoningBlock);
|
|
||||||
|
|
||||||
if (!CSS.supports('field-sizing', 'content')) {
|
|
||||||
const resetHeight = function () {
|
|
||||||
const scrollTop = chatElement.scrollTop;
|
|
||||||
textarea.style.height = '0px';
|
|
||||||
textarea.style.height = `${textarea.scrollHeight}px`;
|
|
||||||
chatElement.scrollTop = scrollTop;
|
|
||||||
};
|
|
||||||
|
|
||||||
textarea.addEventListener('input', resetHeight);
|
|
||||||
resetHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea.focus();
|
|
||||||
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
||||||
|
|
||||||
const textareaRect = textarea.getBoundingClientRect();
|
|
||||||
const chatRect = chatElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
// Scroll if textarea bottom is below visible area
|
|
||||||
if (textareaRect.bottom > chatRect.bottom) {
|
|
||||||
const scrollOffset = textareaRect.bottom - chatRect.bottom;
|
|
||||||
chatElement.scrollTop += scrollOffset;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_reasoning_edit_done', async function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
const { message, messageId, messageBlock } = getMessageFromJquery(this);
|
|
||||||
if (!message?.extra) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const textarea = messageBlock.find('.reasoning_edit_textarea');
|
|
||||||
const reasoning = String(textarea.val());
|
|
||||||
message.extra.reasoning = reasoning;
|
|
||||||
await saveChatConditional();
|
|
||||||
updateMessageBlock(messageId, message);
|
|
||||||
textarea.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_reasoning_edit_cancel', function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const { messageBlock } = getMessageFromJquery(this);
|
|
||||||
const textarea = messageBlock.find('.reasoning_edit_textarea');
|
|
||||||
textarea.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_edit_add_reasoning', async function () {
|
|
||||||
const { message, messageId } = getMessageFromJquery(this);
|
|
||||||
if (!message?.extra) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.extra.reasoning) {
|
|
||||||
toastr.info(t`Reasoning already exists.`, t`Edit Message`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
message.extra.reasoning = PromptReasoning.REASONING_PLACEHOLDER;
|
|
||||||
await saveChatConditional();
|
|
||||||
closeMessageEditor();
|
|
||||||
updateMessageBlock(messageId, message);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '.mes_reasoning_delete', async function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const confirm = await Popup.show.confirm(t`Are you sure you want to clear the reasoning?`, t`Visible message contents will stay intact.`);
|
|
||||||
|
|
||||||
if (!confirm) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { message, messageId } = getMessageFromJquery(this);
|
|
||||||
if (!message?.extra) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
message.extra.reasoning = '';
|
|
||||||
await saveChatConditional();
|
|
||||||
updateMessageBlock(messageId, message);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('pointerup', '.mes_reasoning_copy', async function () {
|
|
||||||
const { message } = getMessageFromJquery(this);
|
|
||||||
const reasoning = message?.extra?.reasoning;
|
|
||||||
|
|
||||||
if (!reasoning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await copyText(reasoning);
|
|
||||||
toastr.info(t`Copied!`, '', { timeOut: 2000 });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#file_form_input').on('change', async () => {
|
$('#file_form_input').on('change', async () => {
|
||||||
const fileInput = document.getElementById('file_form_input');
|
const fileInput = document.getElementById('file_form_input');
|
||||||
if (!(fileInput instanceof HTMLInputElement)) return;
|
if (!(fileInput instanceof HTMLInputElement)) return;
|
||||||
|
@ -1621,7 +1621,6 @@ async function loadPowerUserSettings(settings, data) {
|
|||||||
loadMovingUIState();
|
loadMovingUIState();
|
||||||
loadCharListState();
|
loadCharListState();
|
||||||
toggleMDHotkeyIconDisplay();
|
toggleMDHotkeyIconDisplay();
|
||||||
loadReasoningSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMDHotkeyIconDisplay() {
|
function toggleMDHotkeyIconDisplay() {
|
||||||
@ -1638,38 +1637,6 @@ function loadCharListState() {
|
|||||||
document.body.classList.toggle('charListGrid', power_user.charListGrid);
|
document.body.classList.toggle('charListGrid', power_user.charListGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadReasoningSettings() {
|
|
||||||
$('#reasoning_add_to_prompts').prop('checked', power_user.reasoning.add_to_prompts);
|
|
||||||
$('#reasoning_add_to_prompts').on('change', function () {
|
|
||||||
power_user.reasoning.add_to_prompts = !!$(this).prop('checked');
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#reasoning_prefix').val(power_user.reasoning.prefix);
|
|
||||||
$('#reasoning_prefix').on('input', function () {
|
|
||||||
power_user.reasoning.prefix = String($(this).val());
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#reasoning_suffix').val(power_user.reasoning.suffix);
|
|
||||||
$('#reasoning_suffix').on('input', function () {
|
|
||||||
power_user.reasoning.suffix = String($(this).val());
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#reasoning_separator').val(power_user.reasoning.separator);
|
|
||||||
$('#reasoning_separator').on('input', function () {
|
|
||||||
power_user.reasoning.separator = String($(this).val());
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#reasoning_max_additions').val(power_user.reasoning.max_additions);
|
|
||||||
$('#reasoning_max_additions').on('input', function () {
|
|
||||||
power_user.reasoning.max_additions = Number($(this).val());
|
|
||||||
saveSettingsDebounced();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMovingUIState() {
|
function loadMovingUIState() {
|
||||||
if (!isMobile()
|
if (!isMobile()
|
||||||
&& power_user.movingUIState
|
&& power_user.movingUIState
|
||||||
|
228
public/scripts/reasoning.js
Normal file
228
public/scripts/reasoning.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
import { chat, closeMessageEditor, saveChatConditional, saveSettingsDebounced, substituteParams, updateMessageBlock } from '../script.js';
|
||||||
|
import { t } from './i18n.js';
|
||||||
|
import { Popup } from './popup.js';
|
||||||
|
import { power_user } from './power-user.js';
|
||||||
|
import { copyText } from './utils.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a message from a jQuery element.
|
||||||
|
* @param {Element} element
|
||||||
|
* @returns {{messageId: number, message: object, messageBlock: JQuery<HTMLElement>}}
|
||||||
|
*/
|
||||||
|
function getMessageFromJquery(element) {
|
||||||
|
const messageBlock = $(element).closest('.mes');
|
||||||
|
const messageId = Number(messageBlock.attr('mesid'));
|
||||||
|
const message = chat[messageId];
|
||||||
|
return { messageId: messageId, message, messageBlock };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for adding reasoning to messages.
|
||||||
|
* Keeps track of the number of reasoning additions.
|
||||||
|
*/
|
||||||
|
export class PromptReasoning {
|
||||||
|
static REASONING_PLACEHOLDER = '\u200B';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the limit of reasoning additions has been reached.
|
||||||
|
* @returns {boolean} True if the limit of reasoning additions has been reached, false otherwise.
|
||||||
|
*/
|
||||||
|
isLimitReached() {
|
||||||
|
if (!power_user.reasoning.add_to_prompts) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.counter >= power_user.reasoning.max_additions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add reasoning to a message according to the power user settings.
|
||||||
|
* @param {string} content Message content
|
||||||
|
* @param {string} reasoning Message reasoning
|
||||||
|
* @returns {string} Message content with reasoning
|
||||||
|
*/
|
||||||
|
addToMessage(content, reasoning) {
|
||||||
|
// Disabled or reached limit of additions
|
||||||
|
if (!power_user.reasoning.add_to_prompts || this.counter >= power_user.reasoning.max_additions) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No reasoning provided or a placeholder
|
||||||
|
if (!reasoning || reasoning === PromptReasoning.REASONING_PLACEHOLDER) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the counter
|
||||||
|
this.counter++;
|
||||||
|
|
||||||
|
// Substitute macros in variable parts
|
||||||
|
const prefix = substituteParams(power_user.reasoning.prefix || '');
|
||||||
|
const separator = substituteParams(power_user.reasoning.separator || '');
|
||||||
|
const suffix = substituteParams(power_user.reasoning.suffix || '');
|
||||||
|
|
||||||
|
// Combine parts with reasoning and content
|
||||||
|
return `${prefix}${reasoning}${suffix}${separator}${content}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadReasoningSettings() {
|
||||||
|
$('#reasoning_add_to_prompts').prop('checked', power_user.reasoning.add_to_prompts);
|
||||||
|
$('#reasoning_add_to_prompts').on('change', function () {
|
||||||
|
power_user.reasoning.add_to_prompts = !!$(this).prop('checked');
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#reasoning_prefix').val(power_user.reasoning.prefix);
|
||||||
|
$('#reasoning_prefix').on('input', function () {
|
||||||
|
power_user.reasoning.prefix = String($(this).val());
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#reasoning_suffix').val(power_user.reasoning.suffix);
|
||||||
|
$('#reasoning_suffix').on('input', function () {
|
||||||
|
power_user.reasoning.suffix = String($(this).val());
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#reasoning_separator').val(power_user.reasoning.separator);
|
||||||
|
$('#reasoning_separator').on('input', function () {
|
||||||
|
power_user.reasoning.separator = String($(this).val());
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#reasoning_max_additions').val(power_user.reasoning.max_additions);
|
||||||
|
$('#reasoning_max_additions').on('input', function () {
|
||||||
|
power_user.reasoning.max_additions = Number($(this).val());
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setReasoningEventHandlers(){
|
||||||
|
$(document).on('click', '.mes_reasoning_copy', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.mes_reasoning_edit', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
const { message, messageBlock } = getMessageFromJquery(this);
|
||||||
|
if (!message?.extra) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reasoning = message?.extra?.reasoning;
|
||||||
|
const chatElement = document.getElementById('chat');
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
const reasoningBlock = messageBlock.find('.mes_reasoning');
|
||||||
|
textarea.classList.add('reasoning_edit_textarea');
|
||||||
|
textarea.value = reasoning === PromptReasoning.REASONING_PLACEHOLDER ? '' : reasoning;
|
||||||
|
$(textarea).insertBefore(reasoningBlock);
|
||||||
|
|
||||||
|
if (!CSS.supports('field-sizing', 'content')) {
|
||||||
|
const resetHeight = function () {
|
||||||
|
const scrollTop = chatElement.scrollTop;
|
||||||
|
textarea.style.height = '0px';
|
||||||
|
textarea.style.height = `${textarea.scrollHeight}px`;
|
||||||
|
chatElement.scrollTop = scrollTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
textarea.addEventListener('input', resetHeight);
|
||||||
|
resetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.focus();
|
||||||
|
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
||||||
|
|
||||||
|
const textareaRect = textarea.getBoundingClientRect();
|
||||||
|
const chatRect = chatElement.getBoundingClientRect();
|
||||||
|
|
||||||
|
// Scroll if textarea bottom is below visible area
|
||||||
|
if (textareaRect.bottom > chatRect.bottom) {
|
||||||
|
const scrollOffset = textareaRect.bottom - chatRect.bottom;
|
||||||
|
chatElement.scrollTop += scrollOffset;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.mes_reasoning_edit_done', async function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
const { message, messageId, messageBlock } = getMessageFromJquery(this);
|
||||||
|
if (!message?.extra) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const textarea = messageBlock.find('.reasoning_edit_textarea');
|
||||||
|
const reasoning = String(textarea.val());
|
||||||
|
message.extra.reasoning = reasoning;
|
||||||
|
await saveChatConditional();
|
||||||
|
updateMessageBlock(messageId, message);
|
||||||
|
textarea.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.mes_reasoning_edit_cancel', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const { messageBlock } = getMessageFromJquery(this);
|
||||||
|
const textarea = messageBlock.find('.reasoning_edit_textarea');
|
||||||
|
textarea.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.mes_edit_add_reasoning', async function () {
|
||||||
|
const { message, messageId } = getMessageFromJquery(this);
|
||||||
|
if (!message?.extra) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.extra.reasoning) {
|
||||||
|
toastr.info(t`Reasoning already exists.`, t`Edit Message`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.extra.reasoning = PromptReasoning.REASONING_PLACEHOLDER;
|
||||||
|
await saveChatConditional();
|
||||||
|
closeMessageEditor();
|
||||||
|
updateMessageBlock(messageId, message);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.mes_reasoning_delete', async function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const confirm = await Popup.show.confirm(t`Are you sure you want to clear the reasoning?`, t`Visible message contents will stay intact.`);
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { message, messageId } = getMessageFromJquery(this);
|
||||||
|
if (!message?.extra) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
message.extra.reasoning = '';
|
||||||
|
await saveChatConditional();
|
||||||
|
updateMessageBlock(messageId, message);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('pointerup', '.mes_reasoning_copy', async function () {
|
||||||
|
const { message } = getMessageFromJquery(this);
|
||||||
|
const reasoning = message?.extra?.reasoning;
|
||||||
|
|
||||||
|
if (!reasoning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await copyText(reasoning);
|
||||||
|
toastr.info(t`Copied!`, '', { timeOut: 2000 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initReasoning() {
|
||||||
|
loadReasoningSettings();
|
||||||
|
setReasoningEventHandlers();
|
||||||
|
}
|
Reference in New Issue
Block a user