The THONKening
| @@ -6229,6 +6229,7 @@ | |||
| 6229 | <div class="mes_edit_cancel menu_button fa-solid fa-xmark" title="Cancel" data-i18n="[title]Cancel"></div> | 6229 | <div class="mes_edit_cancel menu_button fa-solid fa-xmark" title="Cancel" data-i18n="[title]Cancel"></div> |
| 6230 | </div> | 6230 | </div> |
| 6231 | </div> | 6231 | </div> |
| 6232 | <div class="mes_reasoning"></div> | ||
| 6232 | <div class="mes_text"></div> | 6233 | <div class="mes_text"></div> |
| 6233 | <div class="mes_img_container"> | 6234 | <div class="mes_img_container"> |
| 6234 | <div class="mes_img_controls"> | 6235 | <div class="mes_img_controls"> |
| @@ -170,7 +170,7 @@ import { | |||
| 170 | isElementInViewport, | 170 | isElementInViewport, |
| 171 | copyText, | 171 | copyText, |
| 172 | } from './scripts/utils.js'; | 172 | } from './scripts/utils.js'; |
| 173 | import { debounce_timeout } from './scripts/constants.js'; | 173 | import { debounce_timeout, THINK_BREAK } from './scripts/constants.js'; |
| 174 | 174 | ||
| 175 | import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js'; | 175 | import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js'; |
| 176 | import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js'; | 176 | import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js'; |
| @@ -2199,6 +2199,7 @@ function getMessageFromTemplate({ | |||
| 2199 | isUser, | 2199 | isUser, |
| 2200 | avatarImg, | 2200 | avatarImg, |
| 2201 | bias, | 2201 | bias, |
| 2202 | reasoning, | ||
| 2202 | isSystem, | 2203 | isSystem, |
| 2203 | title, | 2204 | title, |
| 2204 | timerValue, | 2205 | timerValue, |
| @@ -2223,6 +2224,7 @@ function getMessageFromTemplate({ | |||
| 2223 | mes.find('.avatar img').attr('src', avatarImg); | 2224 | mes.find('.avatar img').attr('src', avatarImg); |
| 2224 | mes.find('.ch_name .name_text').text(characterName); | 2225 | mes.find('.ch_name .name_text').text(characterName); |
| 2225 | mes.find('.mes_bias').html(bias); | 2226 | mes.find('.mes_bias').html(bias); |
| 2227 | mes.find('.mes_reasoning').html(reasoning); | ||
| 2226 | mes.find('.timestamp').text(timestamp).attr('title', `${extra?.api ? extra.api + ' - ' : ''}${extra?.model ?? ''}`); | 2228 | mes.find('.timestamp').text(timestamp).attr('title', `${extra?.api ? extra.api + ' - ' : ''}${extra?.model ?? ''}`); |
| 2227 | mes.find('.mesIDDisplay').text(`#${mesId}`); | 2229 | mes.find('.mesIDDisplay').text(`#${mesId}`); |
| 2228 | tokenCount && mes.find('.tokenCounterDisplay').text(`${tokenCount}t`); | 2230 | tokenCount && mes.find('.tokenCounterDisplay').text(`${tokenCount}t`); |
| @@ -2241,6 +2243,7 @@ export function updateMessageBlock(messageId, message) { | |||
| 2241 | const messageElement = $(`#chat [mesid="${messageId}"]`); | 2243 | const messageElement = $(`#chat [mesid="${messageId}"]`); |
| 2242 | const text = message?.extra?.display_text ?? message.mes; | 2244 | const text = message?.extra?.display_text ?? message.mes; |
| 2243 | messageElement.find('.mes_text').html(messageFormatting(text, message.name, message.is_system, message.is_user, messageId)); | 2245 | messageElement.find('.mes_text').html(messageFormatting(text, message.name, message.is_system, message.is_user, messageId)); |
| 2246 | messageElement.find('.mes_reasoning').html(messageFormatting(message.extra?.reasoning ?? '', '', false, false, -1)); | ||
| 2244 | addCopyToCodeBlocks(messageElement); | 2247 | addCopyToCodeBlocks(messageElement); |
| 2245 | appendMediaToMessage(message, messageElement); | 2248 | appendMediaToMessage(message, messageElement); |
| 2246 | } | 2249 | } |
| @@ -2399,6 +2402,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | |||
| 2399 | sanitizerOverrides, | 2402 | sanitizerOverrides, |
| 2400 | ); | 2403 | ); |
| 2401 | const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1); | 2404 | const bias = messageFormatting(mes.extra?.bias ?? '', '', false, false, -1); |
| 2405 | const reasoning = messageFormatting(mes.extra?.reasoning ?? '', '', false, false, -1); | ||
| 2402 | let bookmarkLink = mes?.extra?.bookmark_link ?? ''; | 2406 | let bookmarkLink = mes?.extra?.bookmark_link ?? ''; |
| 2403 | 2407 | ||
| 2404 | let params = { | 2408 | let params = { |
| @@ -2408,6 +2412,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | |||
| 2408 | isUser: mes.is_user, | 2412 | isUser: mes.is_user, |
| 2409 | avatarImg: avatarImg, | 2413 | avatarImg: avatarImg, |
| 2410 | bias: bias, | 2414 | bias: bias, |
| 2415 | reasoning: reasoning, | ||
| 2411 | isSystem: isSystem, | 2416 | isSystem: isSystem, |
| 2412 | title: title, | 2417 | title: title, |
| 2413 | bookmarkLink: bookmarkLink, | 2418 | bookmarkLink: bookmarkLink, |
| @@ -2467,6 +2472,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | |||
| 2467 | const swipeMessage = chatElement.find(`[mesid="${chat.length - 1}"]`); | 2472 | const swipeMessage = chatElement.find(`[mesid="${chat.length - 1}"]`); |
| 2468 | swipeMessage.attr('swipeid', params.swipeId); | 2473 | swipeMessage.attr('swipeid', params.swipeId); |
| 2469 | swipeMessage.find('.mes_text').html(messageText).attr('title', title); | 2474 | swipeMessage.find('.mes_text').html(messageText).attr('title', title); |
| 2475 | swipeMessage.find('.mes_reasoning').html(reasoning); | ||
| 2470 | swipeMessage.find('.timestamp').text(timestamp).attr('title', `${params.extra.api} - ${params.extra.model}`); | 2476 | swipeMessage.find('.timestamp').text(timestamp).attr('title', `${params.extra.api} - ${params.extra.model}`); |
| 2471 | appendMediaToMessage(mes, swipeMessage); | 2477 | appendMediaToMessage(mes, swipeMessage); |
| 2472 | if (power_user.timestamp_model_icon && params.extra?.api) { | 2478 | if (power_user.timestamp_model_icon && params.extra?.api) { |
| @@ -3077,6 +3083,7 @@ class StreamingProcessor { | |||
| 3077 | this.messageTextDom = null; | 3083 | this.messageTextDom = null; |
| 3078 | this.messageTimerDom = null; | 3084 | this.messageTimerDom = null; |
| 3079 | this.messageTokenCounterDom = null; | 3085 | this.messageTokenCounterDom = null; |
| 3086 | this.messageReasoningDom = null; | ||
| 3080 | /** @type {HTMLTextAreaElement} */ | 3087 | /** @type {HTMLTextAreaElement} */ |
| 3081 | this.sendTextarea = document.querySelector('#send_textarea'); | 3088 | this.sendTextarea = document.querySelector('#send_textarea'); |
| 3082 | this.type = type; | 3089 | this.type = type; |
| @@ -3092,6 +3099,7 @@ class StreamingProcessor { | |||
| 3092 | /** @type {import('./scripts/logprobs.js').TokenLogprobs[]} */ | 3099 | /** @type {import('./scripts/logprobs.js').TokenLogprobs[]} */ |
| 3093 | this.messageLogprobs = []; | 3100 | this.messageLogprobs = []; |
| 3094 | this.toolCalls = []; | 3101 | this.toolCalls = []; |
| 3102 | this.reasoning = ''; | ||
| 3095 | } | 3103 | } |
| 3096 | 3104 | ||
| 3097 | #checkDomElements(messageId) { | 3105 | #checkDomElements(messageId) { |
| @@ -3100,6 +3108,7 @@ class StreamingProcessor { | |||
| 3100 | this.messageTextDom = this.messageDom?.querySelector('.mes_text'); | 3108 | this.messageTextDom = this.messageDom?.querySelector('.mes_text'); |
| 3101 | this.messageTimerDom = this.messageDom?.querySelector('.mes_timer'); | 3109 | this.messageTimerDom = this.messageDom?.querySelector('.mes_timer'); |
| 3102 | this.messageTokenCounterDom = this.messageDom?.querySelector('.tokenCounterDisplay'); | 3110 | this.messageTokenCounterDom = this.messageDom?.querySelector('.tokenCounterDisplay'); |
| 3111 | this.messageReasoningDom = this.messageDom?.querySelector('.mes_reasoning'); | ||
| 3103 | } | 3112 | } |
| 3104 | } | 3113 | } |
| 3105 | 3114 | ||
| @@ -3184,11 +3193,17 @@ class StreamingProcessor { | |||
| 3184 | chat[messageId]['gen_started'] = this.timeStarted; | 3193 | chat[messageId]['gen_started'] = this.timeStarted; |
| 3185 | chat[messageId]['gen_finished'] = currentTime; | 3194 | chat[messageId]['gen_finished'] = currentTime; |
| 3186 | 3195 | ||
| 3187 | if (currentTokenCount) { | ||
| 3188 | if (!chat[messageId]['extra']) { | 3196 | if (!chat[messageId]['extra']) { |
| 3189 | chat[messageId]['extra'] = {}; | 3197 | chat[messageId]['extra'] = {}; |
| 3190 | } | 3198 | } |
| 3191 | 3199 | ||
| 3200 | if (this.reasoning && this.messageReasoningDom instanceof HTMLElement) { | ||
| 3201 | chat[messageId]['extra']['reasoning'] = this.reasoning; | ||
| 3202 | const formattedReasoning = messageFormatting(this.reasoning, '', false, false, -1); | ||
| 3203 | this.messageReasoningDom.innerHTML = formattedReasoning; | ||
| 3204 | } | ||
| 3205 | |||
| 3206 | if (currentTokenCount) { | ||
| 3192 | chat[messageId]['extra']['token_count'] = currentTokenCount; | 3207 | chat[messageId]['extra']['token_count'] = currentTokenCount; |
| 3193 | if (this.messageTokenCounterDom instanceof HTMLElement) { | 3208 | if (this.messageTokenCounterDom instanceof HTMLElement) { |
| 3194 | this.messageTokenCounterDom.textContent = `${currentTokenCount}t`; | 3209 | this.messageTokenCounterDom.textContent = `${currentTokenCount}t`; |
| @@ -3320,7 +3335,7 @@ class StreamingProcessor { | |||
| 3320 | } | 3335 | } |
| 3321 | 3336 | ||
| 3322 | /** | 3337 | /** |
| 3323 | * @returns {Generator<{ text: string, swipes: string[], logprobs: import('./scripts/logprobs.js').TokenLogprobs, toolCalls: any[] }, void, void>} | 3338 | * @returns {Generator<{ text: string, swipes: string[], logprobs: import('./scripts/logprobs.js').TokenLogprobs, toolCalls: any[], state: any }, void, void>} |
| 3324 | */ | 3339 | */ |
| 3325 | *nullStreamingGeneration() { | 3340 | *nullStreamingGeneration() { |
| 3326 | throw new Error('Generation function for streaming is not hooked up'); | 3341 | throw new Error('Generation function for streaming is not hooked up'); |
| @@ -3342,7 +3357,7 @@ class StreamingProcessor { | |||
| 3342 | try { | 3357 | try { |
| 3343 | const sw = new Stopwatch(1000 / power_user.streaming_fps); | 3358 | const sw = new Stopwatch(1000 / power_user.streaming_fps); |
| 3344 | const timestamps = []; | 3359 | const timestamps = []; |
| 3345 | for await (const { text, swipes, logprobs, toolCalls } of this.generator()) { | 3360 | for await (const { text, swipes, logprobs, toolCalls, state } of this.generator()) { |
| 3346 | timestamps.push(Date.now()); | 3361 | timestamps.push(Date.now()); |
| 3347 | if (this.isStopped) { | 3362 | if (this.isStopped) { |
| 3348 | return; | 3363 | return; |
| @@ -3354,6 +3369,7 @@ class StreamingProcessor { | |||
| 3354 | if (logprobs) { | 3369 | if (logprobs) { |
| 3355 | this.messageLogprobs.push(...(Array.isArray(logprobs) ? logprobs : [logprobs])); | 3370 | this.messageLogprobs.push(...(Array.isArray(logprobs) ? logprobs : [logprobs])); |
| 3356 | } | 3371 | } |
| 3372 | this.reasoning = state?.reasoning ?? ''; | ||
| 3357 | await eventSource.emit(event_types.STREAM_TOKEN_RECEIVED, text); | 3373 | await eventSource.emit(event_types.STREAM_TOKEN_RECEIVED, text); |
| 3358 | await sw.tick(() => this.onProgressStreaming(this.messageId, this.continueMessage + text)); | 3374 | await sw.tick(() => this.onProgressStreaming(this.messageId, this.continueMessage + text)); |
| 3359 | } | 3375 | } |
| @@ -4741,6 +4757,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4741 | //const getData = await response.json(); | 4757 | //const getData = await response.json(); |
| 4742 | let getMessage = extractMessageFromData(data); | 4758 | let getMessage = extractMessageFromData(data); |
| 4743 | let title = extractTitleFromData(data); | 4759 | let title = extractTitleFromData(data); |
| 4760 | let reasoning = extractReasoningFromData(data); | ||
| 4744 | kobold_horde_model = title; | 4761 | kobold_horde_model = title; |
| 4745 | 4762 | ||
| 4746 | const swipes = extractMultiSwipes(data, type); | 4763 | const swipes = extractMultiSwipes(data, type); |
| @@ -4767,10 +4784,10 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4767 | else { | 4784 | else { |
| 4768 | // Without streaming we'll be having a full message on continuation. Treat it as a last chunk. | 4785 | // Without streaming we'll be having a full message on continuation. Treat it as a last chunk. |
| 4769 | if (originalType !== 'continue') { | 4786 | if (originalType !== 'continue') { |
| 4770 | ({ type, getMessage } = await saveReply(type, getMessage, false, title, swipes)); | 4787 | ({ type, getMessage } = await saveReply(type, getMessage, false, title, swipes, reasoning)); |
| 4771 | } | 4788 | } |
| 4772 | else { | 4789 | else { |
| 4773 | ({ type, getMessage } = await saveReply('appendFinal', getMessage, false, title, swipes)); | 4790 | ({ type, getMessage } = await saveReply('appendFinal', getMessage, false, title, swipes, reasoning)); |
| 4774 | } | 4791 | } |
| 4775 | 4792 | ||
| 4776 | // This relies on `saveReply` having been called to add the message to the chat, so it must be last. | 4793 | // This relies on `saveReply` having been called to add the message to the chat, so it must be last. |
| @@ -5649,16 +5666,15 @@ function parseAndSaveLogprobs(data, continueFrom) { | |||
| 5649 | } | 5666 | } |
| 5650 | 5667 | ||
| 5651 | /** | 5668 | /** |
| 5652 | * Extracts the message from the response data. | 5669 | * Gets the text context from the response data. |
| 5653 | * @param {object} data Response data | 5670 | * @param {object} data Response JSON data |
| 5654 | * @returns {string} Extracted message | 5671 | * @returns {string} Extracted text |
| 5655 | */ | 5672 | */ |
| 5656 | function extractMessageFromData(data) { | 5673 | function getTextContextFromData(data) { |
| 5657 | if (typeof data === 'string') { | 5674 | if (typeof data === 'string') { |
| 5658 | return data; | 5675 | return data; |
| 5659 | } | 5676 | } |
| 5660 | 5677 | ||
| 5661 | function getTextContext() { | ||
| 5662 | switch (main_api) { | 5678 | switch (main_api) { |
| 5663 | case 'kobold': | 5679 | case 'kobold': |
| 5664 | return data.results[0].text; | 5680 | return data.results[0].text; |
| @@ -5675,17 +5691,41 @@ function extractMessageFromData(data) { | |||
| 5675 | } | 5691 | } |
| 5676 | } | 5692 | } |
| 5677 | 5693 | ||
| 5678 | const content = getTextContext(); | 5694 | /** |
| 5695 | * Extracts the message from the response data. | ||
| 5696 | * @param {object} data Response data | ||
| 5697 | * @returns {string} Extracted message | ||
| 5698 | */ | ||
| 5699 | function extractMessageFromData(data){ | ||
| 5700 | const content = String(getTextContextFromData(data) ?? ''); | ||
| 5679 | 5701 | ||
| 5680 | if (main_api === 'openai' && oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK && oai_settings.show_thoughts) { | 5702 | if (content.includes(THINK_BREAK)) { |
| 5681 | const thoughts = data?.choices?.[0]?.message?.reasoning_content ?? ''; | 5703 | return content.split(THINK_BREAK)[1]; |
| 5682 | return [thoughts, content].filter(x => x).join('\n\n'); | ||
| 5683 | } | 5704 | } |
| 5684 | 5705 | ||
| 5685 | return content; | 5706 | return content; |
| 5686 | } | 5707 | } |
| 5687 | 5708 | ||
| 5688 | /** | 5709 | /** |
| 5710 | * Extracts the reasoning from the response data. | ||
| 5711 | * @param {object} data Response data | ||
| 5712 | * @returns {string} Extracted reasoning | ||
| 5713 | */ | ||
| 5714 | function extractReasoningFromData(data) { | ||
| 5715 | const content = String(getTextContextFromData(data) ?? ''); | ||
| 5716 | |||
| 5717 | if (content.includes(THINK_BREAK)) { | ||
| 5718 | return content.split(THINK_BREAK)[0]; | ||
| 5719 | } | ||
| 5720 | |||
| 5721 | if (main_api === 'openai' && oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK && oai_settings.show_thoughts) { | ||
| 5722 | return data?.choices?.[0]?.message?.reasoning_content ?? ''; | ||
| 5723 | } | ||
| 5724 | |||
| 5725 | return ''; | ||
| 5726 | } | ||
| 5727 | |||
| 5728 | /** | ||
| 5689 | * Extracts multiswipe swipes from the response data. | 5729 | * Extracts multiswipe swipes from the response data. |
| 5690 | * @param {Object} data Response data | 5730 | * @param {Object} data Response data |
| 5691 | * @param {string} type Type of generation | 5731 | * @param {string} type Type of generation |
| @@ -5865,7 +5905,7 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc | |||
| 5865 | return getMessage; | 5905 | return getMessage; |
| 5866 | } | 5906 | } |
| 5867 | 5907 | ||
| 5868 | export async function saveReply(type, getMessage, fromStreaming, title, swipes) { | 5908 | export async function saveReply(type, getMessage, fromStreaming, title, swipes, reasoning) { |
| 5869 | if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined || | 5909 | if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined || |
| 5870 | chat[chat.length - 1]['is_user'])) { | 5910 | chat[chat.length - 1]['is_user'])) { |
| 5871 | type = 'normal'; | 5911 | type = 'normal'; |
| @@ -5890,6 +5930,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes) | |||
| 5890 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); | 5930 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); |
| 5891 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); | 5931 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); |
| 5892 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); | 5932 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); |
| 5933 | chat[chat.length - 1]['extra']['reasoning'] = reasoning; | ||
| 5893 | if (power_user.message_token_count_enabled) { | 5934 | if (power_user.message_token_count_enabled) { |
| 5894 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); | 5935 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); |
| 5895 | } | 5936 | } |
| @@ -5910,6 +5951,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes) | |||
| 5910 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); | 5951 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); |
| 5911 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); | 5952 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); |
| 5912 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); | 5953 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); |
| 5954 | chat[chat.length - 1]['extra']['reasoning'] += reasoning; | ||
| 5913 | if (power_user.message_token_count_enabled) { | 5955 | if (power_user.message_token_count_enabled) { |
| 5914 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); | 5956 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); |
| 5915 | } | 5957 | } |
| @@ -5927,6 +5969,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes) | |||
| 5927 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); | 5969 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); |
| 5928 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); | 5970 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); |
| 5929 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); | 5971 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); |
| 5972 | chat[chat.length - 1]['extra']['reasoning'] += reasoning; | ||
| 5930 | if (power_user.message_token_count_enabled) { | 5973 | if (power_user.message_token_count_enabled) { |
| 5931 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); | 5974 | chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(chat[chat.length - 1]['mes'], 0); |
| 5932 | } | 5975 | } |
| @@ -5944,6 +5987,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes) | |||
| 5944 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); | 5987 | chat[chat.length - 1]['send_date'] = getMessageTimeStamp(); |
| 5945 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); | 5988 | chat[chat.length - 1]['extra']['api'] = getGeneratingApi(); |
| 5946 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); | 5989 | chat[chat.length - 1]['extra']['model'] = getGeneratingModel(); |
| 5990 | chat[chat.length - 1]['extra']['reasoning'] = reasoning; | ||
| 5947 | if (power_user.trim_spaces) { | 5991 | if (power_user.trim_spaces) { |
| 5948 | getMessage = getMessage.trim(); | 5992 | getMessage = getMessage.trim(); |
| 5949 | } | 5993 | } |
| @@ -8646,6 +8690,7 @@ const swipe_right = () => { | |||
| 8646 | // resets the timer | 8690 | // resets the timer |
| 8647 | swipeMessage.find('.mes_timer').html(''); | 8691 | swipeMessage.find('.mes_timer').html(''); |
| 8648 | swipeMessage.find('.tokenCounterDisplay').text(''); | 8692 | swipeMessage.find('.tokenCounterDisplay').text(''); |
| 8693 | swipeMessage.find('.mes_reasoning').html(''); | ||
| 8649 | } else { | 8694 | } else { |
| 8650 | //console.log('showing previously generated swipe candidate, or "..."'); | 8695 | //console.log('showing previously generated swipe candidate, or "..."'); |
| 8651 | //console.log('onclick right swipe calling addOneMessage'); | 8696 | //console.log('onclick right swipe calling addOneMessage'); |
| @@ -14,3 +14,8 @@ export const debounce_timeout = { | |||
| 14 | /** [5 sec] For delayed tasks, like auto-saving or completing batch operations that need a significant pause. */ | 14 | /** [5 sec] For delayed tasks, like auto-saving or completing batch operations that need a significant pause. */ |
| 15 | extended: 5000, | 15 | extended: 5000, |
| 16 | }; | 16 | }; |
| 17 | |||
| 18 | /** | ||
| 19 | * Custom boundary for splitting the text between the model's reasoning and the actual response. | ||
| 20 | */ | ||
| 21 | export const THINK_BREAK = '##�THINK_BREAK�##'; | ||
| @@ -188,7 +188,7 @@ export async function generateKoboldWithStreaming(generate_data, signal) { | |||
| 188 | if (data?.token) { | 188 | if (data?.token) { |
| 189 | text += data.token; | 189 | text += data.token; |
| 190 | } | 190 | } |
| 191 | yield { text, swipes: [], toolCalls: [] }; | 191 | yield { text, swipes: [], toolCalls: [], state: {} }; |
| 192 | } | 192 | } |
| 193 | }; | 193 | }; |
| 194 | } | 194 | } |
| @@ -746,7 +746,7 @@ export async function generateNovelWithStreaming(generate_data, signal) { | |||
| 746 | text += data.token; | 746 | text += data.token; |
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | yield { text, swipes: [], logprobs: parseNovelAILogprobs(data.logprobs), toolCalls: [] }; | 749 | yield { text, swipes: [], logprobs: parseNovelAILogprobs(data.logprobs), toolCalls: [], state: {} }; |
| 750 | } | 750 | } |
| 751 | }; | 751 | }; |
| 752 | } | 752 | } |
| @@ -2095,7 +2095,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2095 | let text = ''; | 2095 | let text = ''; |
| 2096 | const swipes = []; | 2096 | const swipes = []; |
| 2097 | const toolCalls = []; | 2097 | const toolCalls = []; |
| 2098 | const state = {}; | 2098 | const state = { reasoning: '' }; |
| 2099 | while (true) { | 2099 | while (true) { |
| 2100 | const { done, value } = await reader.read(); | 2100 | const { done, value } = await reader.read(); |
| 2101 | if (done) return; | 2101 | if (done) return; |
| @@ -2113,7 +2113,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2113 | 2113 | ||
| 2114 | ToolManager.parseToolCalls(toolCalls, parsed); | 2114 | ToolManager.parseToolCalls(toolCalls, parsed); |
| 2115 | 2115 | ||
| 2116 | yield { text, swipes: swipes, logprobs: parseChatCompletionLogprobs(parsed), toolCalls: toolCalls }; | 2116 | yield { text, swipes: swipes, logprobs: parseChatCompletionLogprobs(parsed), toolCalls: toolCalls, state: state }; |
| 2117 | } | 2117 | } |
| 2118 | }; | 2118 | }; |
| 2119 | } | 2119 | } |
| @@ -2150,16 +2150,17 @@ function getStreamingReply(data, state) { | |||
| 2150 | if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) { | 2150 | if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) { |
| 2151 | return data?.delta?.text || ''; | 2151 | return data?.delta?.text || ''; |
| 2152 | } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) { | 2152 | } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) { |
| 2153 | return data?.candidates?.[0]?.content?.parts?.filter(x => oai_settings.show_thoughts || !x.thought)?.map(x => x.text)?.filter(x => x)?.join('\n\n') || ''; | 2153 | if (oai_settings.show_thoughts) { |
| 2154 | state.reasoning += (data?.candidates?.[0]?.content?.parts?.filter(x => x.thought)?.map(x => x.text)?.[0] || ''); | ||
| 2155 | } | ||
| 2156 | return data?.candidates?.[0]?.content?.parts?.filter(x => !x.thought)?.map(x => x.text)?.[0] || ''; | ||
| 2154 | } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) { | 2157 | } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) { |
| 2155 | return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || ''; | 2158 | return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || ''; |
| 2156 | } else if (oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK) { | 2159 | } else if (oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK) { |
| 2157 | const hadThoughts = state.hadThoughts; | 2160 | if (oai_settings.show_thoughts) { |
| 2158 | const thoughts = data.choices?.filter(x => oai_settings.show_thoughts || !x?.delta?.reasoning_content)?.[0]?.delta?.reasoning_content || ''; | 2161 | state.reasoning += (data.choices?.filter(x => x?.delta?.reasoning_content)?.[0]?.delta?.reasoning_content || ''); |
| 2159 | const content = data.choices?.[0]?.delta?.content || ''; | 2162 | } |
| 2160 | state.hadThoughts = !!thoughts; | 2163 | return data.choices?.[0]?.delta?.content || ''; |
| 2161 | const separator = hadThoughts && !thoughts ? '\n\n' : ''; | ||
| 2162 | return [thoughts, separator, content].filter(x => x).join('\n\n'); | ||
| 2163 | } else { | 2164 | } else { |
| 2164 | return data.choices?.[0]?.delta?.content ?? data.choices?.[0]?.message?.content ?? data.choices?.[0]?.text ?? ''; | 2165 | return data.choices?.[0]?.delta?.content ?? data.choices?.[0]?.message?.content ?? data.choices?.[0]?.text ?? ''; |
| 2165 | } | 2166 | } |
| @@ -986,6 +986,7 @@ export async function generateTextGenWithStreaming(generate_data, signal) { | |||
| 986 | let logprobs = null; | 986 | let logprobs = null; |
| 987 | const swipes = []; | 987 | const swipes = []; |
| 988 | const toolCalls = []; | 988 | const toolCalls = []; |
| 989 | const state = {}; | ||
| 989 | while (true) { | 990 | while (true) { |
| 990 | const { done, value } = await reader.read(); | 991 | const { done, value } = await reader.read(); |
| 991 | if (done) return; | 992 | if (done) return; |
| @@ -1004,7 +1005,7 @@ export async function generateTextGenWithStreaming(generate_data, signal) { | |||
| 1004 | logprobs = parseTextgenLogprobs(newText, data.choices?.[0]?.logprobs || data?.completion_probabilities); | 1005 | logprobs = parseTextgenLogprobs(newText, data.choices?.[0]?.logprobs || data?.completion_probabilities); |
| 1005 | } | 1006 | } |
| 1006 | 1007 | ||
| 1007 | yield { text, swipes, logprobs, toolCalls }; | 1008 | yield { text, swipes, logprobs, toolCalls, state }; |
| 1008 | } | 1009 | } |
| 1009 | }; | 1010 | }; |
| 1010 | } | 1011 | } |
| @@ -332,6 +332,23 @@ input[type='checkbox']:focus-visible { | |||
| 332 | color: var(--SmartThemeQuoteColor); | 332 | color: var(--SmartThemeQuoteColor); |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | .mes_reasoning { | ||
| 336 | display: block; | ||
| 337 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 338 | background-color: var(--black30a); | ||
| 339 | border-radius: 5px; | ||
| 340 | padding: 5px; | ||
| 341 | margin: 5px 0; | ||
| 342 | overflow-y: auto; | ||
| 343 | max-height: 100px; | ||
| 344 | } | ||
| 345 | |||
| 346 | .mes_block:has(.edit_textarea) .mes_reasoning, | ||
| 347 | .mes_bias:empty, | ||
| 348 | .mes_reasoning:empty { | ||
| 349 | display: none; | ||
| 350 | } | ||
| 351 | |||
| 335 | .mes_text i, | 352 | .mes_text i, |
| 336 | .mes_text em { | 353 | .mes_text em { |
| 337 | color: var(--SmartThemeEmColor); | 354 | color: var(--SmartThemeEmColor); |
| @@ -1022,6 +1039,7 @@ body .panelControlBar { | |||
| 1022 | /*only affects bubblechat to make it sit nicely at the bottom*/ | 1039 | /*only affects bubblechat to make it sit nicely at the bottom*/ |
| 1023 | } | 1040 | } |
| 1024 | 1041 | ||
| 1042 | .last_mes .mes_reasoning, | ||
| 1025 | .last_mes .mes_text { | 1043 | .last_mes .mes_text { |
| 1026 | padding-right: 30px; | 1044 | padding-right: 30px; |
| 1027 | } | 1045 | } |
| @@ -1235,14 +1253,18 @@ body.swipeAllMessages .mes:not(.last_mes) .swipes-counter { | |||
| 1235 | overflow-y: clip; | 1253 | overflow-y: clip; |
| 1236 | } | 1254 | } |
| 1237 | 1255 | ||
| 1238 | .mes_text { | 1256 | .mes_text, |
| 1257 | .mes_reasoning { | ||
| 1239 | font-weight: 500; | 1258 | font-weight: 500; |
| 1240 | line-height: calc(var(--mainFontSize) + .5rem); | 1259 | line-height: calc(var(--mainFontSize) + .5rem); |
| 1260 | max-width: 100%; | ||
| 1261 | overflow-wrap: anywhere; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | .mes_text { | ||
| 1241 | padding-left: 0; | 1265 | padding-left: 0; |
| 1242 | padding-top: 5px; | 1266 | padding-top: 5px; |
| 1243 | padding-bottom: 5px; | 1267 | padding-bottom: 5px; |
| 1244 | max-width: 100%; | ||
| 1245 | overflow-wrap: anywhere; | ||
| 1246 | } | 1268 | } |
| 1247 | 1269 | ||
| 1248 | br { | 1270 | br { |
| @@ -413,3 +413,8 @@ export const VLLM_KEYS = [ | |||
| 413 | 'guided_decoding_backend', | 413 | 'guided_decoding_backend', |
| 414 | 'guided_whitespace_pattern', | 414 | 'guided_whitespace_pattern', |
| 415 | ]; | 415 | ]; |
| 416 | |||
| 417 | /** | ||
| 418 | * Custom boundary for splitting the text between the model's reasoning and the actual response. | ||
| 419 | */ | ||
| 420 | export const THINK_BREAK = '##�THINK_BREAK�##'; | ||
| @@ -7,6 +7,7 @@ import { | |||
| 7 | CHAT_COMPLETION_SOURCES, | 7 | CHAT_COMPLETION_SOURCES, |
| 8 | GEMINI_SAFETY, | 8 | GEMINI_SAFETY, |
| 9 | OPENROUTER_HEADERS, | 9 | OPENROUTER_HEADERS, |
| 10 | THINK_BREAK, | ||
| 10 | } from '../../constants.js'; | 11 | } from '../../constants.js'; |
| 11 | import { | 12 | import { |
| 12 | forwardFetchResponse, | 13 | forwardFetchResponse, |
| @@ -389,7 +390,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 389 | responseContent.parts = responseContent.parts.filter(part => !part.thought); | 390 | responseContent.parts = responseContent.parts.filter(part => !part.thought); |
| 390 | } | 391 | } |
| 391 | 392 | ||
| 392 | const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.map(part => part.text)?.join('\n\n'); | 393 | const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.map(part => part.text)?.join(THINK_BREAK); |
| 393 | if (!responseText) { | 394 | if (!responseText) { |
| 394 | let message = 'Google AI Studio Candidate text empty'; | 395 | let message = 'Google AI Studio Candidate text empty'; |
| 395 | console.log(message, generateResponseJson); | 396 | console.log(message, generateResponseJson); |