Merge branch 'staging' into hidden-reasoning-tracking

d1018a824c3303a96758680459ac735b351ffca9

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

6 files changed, +30 -7Ignore whitespace
public/index.html+1 -1
@@ -1934,7 +1934,7 @@
1934 </span>1934 </span>
1935 </div>1935 </div>
1936 </div>1936 </div>
1937 <div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq">1937 <div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq,deepseek">
1938 <label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">1938 <label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">
1939 <input id="openai_function_calling" type="checkbox" />1939 <input id="openai_function_calling" type="checkbox" />
1940 <span data-i18n="Enable function calling">Enable function calling</span>1940 <span data-i18n="Enable function calling">Enable function calling</span>
public/script.js+3 -2
@@ -269,7 +269,7 @@ import { initSettingsSearch } from './scripts/setting-search.js';
269import { initBulkEdit } from './scripts/bulk-edit.js';269import { initBulkEdit } from './scripts/bulk-edit.js';
270import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';270import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
271import { getContext } from './scripts/st-context.js';271import { getContext } from './scripts/st-context.js';
272import { extractReasoningFromData, initReasoning, PromptReasoning, ReasoningHandler, updateReasoningUI } from './scripts/reasoning.js';272import { extractReasoningFromData, initReasoning, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js';
273273
274// API OBJECT FOR EXTERNAL WIRING274// API OBJECT FOR EXTERNAL WIRING
275globalThis.SillyTavern = {275globalThis.SillyTavern = {
@@ -2785,7 +2785,8 @@ export async function generateQuietPrompt(quiet_prompt, quietToLoud, skipWIAN, q
2785 TempResponseLength.save(main_api, responseLength);2785 TempResponseLength.save(main_api, responseLength);
2786 eventHook = TempResponseLength.setupEventHook(main_api);2786 eventHook = TempResponseLength.setupEventHook(main_api);
2787 }2787 }
2788 return await Generate('quiet', options);2788 const result = await Generate('quiet', options);
2789 return removeReasoningFromString(result);
2789 } finally {2790 } finally {
2790 if (responseLengthCustomized && TempResponseLength.isCustomized()) {2791 if (responseLengthCustomized && TempResponseLength.isCustomized()) {
2791 TempResponseLength.restore(main_api);2792 TempResponseLength.restore(main_api);
public/scripts/openai.js+6 -4
@@ -1916,6 +1916,10 @@ async function sendOpenAIRequest(type, messages, signal) {
1916 'reasoning_effort': String(oai_settings.reasoning_effort),1916 'reasoning_effort': String(oai_settings.reasoning_effort),
1917 };1917 };
19181918
1919 if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) {
1920 await ToolManager.registerFunctionToolsOpenAI(generate_data);
1921 }
1922
1919 // Empty array will produce a validation error1923 // Empty array will produce a validation error
1920 if (!Array.isArray(generate_data.stop) || !generate_data.stop.length) {1924 if (!Array.isArray(generate_data.stop) || !generate_data.stop.length) {
1921 delete generate_data.stop;1925 delete generate_data.stop;
@@ -2039,6 +2043,8 @@ async function sendOpenAIRequest(type, messages, signal) {
2039 delete generate_data.top_logprobs;2043 delete generate_data.top_logprobs;
2040 delete generate_data.logprobs;2044 delete generate_data.logprobs;
2041 delete generate_data.logit_bias;2045 delete generate_data.logit_bias;
2046 delete generate_data.tools;
2047 delete generate_data.tool_choice;
2042 }2048 }
2043 }2049 }
20442050
@@ -2046,10 +2052,6 @@ async function sendOpenAIRequest(type, messages, signal) {
2046 generate_data['seed'] = oai_settings.seed;2052 generate_data['seed'] = oai_settings.seed;
2047 }2053 }
20482054
2049 if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) {
2050 await ToolManager.registerFunctionToolsOpenAI(generate_data);
2051 }
2052
2053 if (isOAI && (oai_settings.openai_model.startsWith('o1') || oai_settings.openai_model.startsWith('o3'))) {2055 if (isOAI && (oai_settings.openai_model.startsWith('o1') || oai_settings.openai_model.startsWith('o3'))) {
2054 generate_data.messages.forEach((msg) => {2056 generate_data.messages.forEach((msg) => {
2055 if (msg.role === 'system') {2057 if (msg.role === 'system') {
public/scripts/reasoning.js+14 -0
@@ -768,6 +768,20 @@ function setReasoningEventHandlers() {
768}768}
769769
770/**770/**
771 * Removes reasoning from a string if auto-parsing is enabled.
772 * @param {string} str Input string
773 * @returns {string} Output string
774 */
775export function removeReasoningFromString(str) {
776 if (!power_user.reasoning.auto_parse) {
777 return str;
778 }
779
780 const parsedReasoning = parseReasoningFromString(str);
781 return parsedReasoning?.content ?? str;
782}
783
784/**
771 * Parses reasoning from a string using the power user reasoning settings.785 * Parses reasoning from a string using the power user reasoning settings.
772 * @typedef {Object} ParsedReasoning786 * @typedef {Object} ParsedReasoning
773 * @property {string} reasoning Reasoning block787 * @property {string} reasoning Reasoning block
public/scripts/tool-calling.js+1 -0
@@ -563,6 +563,7 @@ export class ToolManager {
563 chat_completion_sources.OPENROUTER,563 chat_completion_sources.OPENROUTER,
564 chat_completion_sources.GROQ,564 chat_completion_sources.GROQ,
565 chat_completion_sources.COHERE,565 chat_completion_sources.COHERE,
566 chat_completion_sources.DEEPSEEK,
566 ];567 ];
567 return supportedSources.includes(oai_settings.chat_completion_source);568 return supportedSources.includes(oai_settings.chat_completion_source);
568 }569 }
src/endpoints/backends/chat-completions.js+5 -0
@@ -672,6 +672,11 @@ async function sendDeepSeekRequest(request, response) {
672 bodyParams['logprobs'] = true;672 bodyParams['logprobs'] = true;
673 }673 }
674674
675 if (Array.isArray(request.body.tools) && request.body.tools.length > 0) {
676 bodyParams['tools'] = request.body.tools;
677 bodyParams['tool_choice'] = request.body.tool_choice;
678 }
679
675 const postProcessType = String(request.body.model).endsWith('-reasoner') ? 'deepseek-reasoner' : 'deepseek';680 const postProcessType = String(request.body.model).endsWith('-reasoner') ? 'deepseek-reasoner' : 'deepseek';
676 const processedMessages = postProcessPrompt(request.body.messages, postProcessType, getPromptNames(request));681 const processedMessages = postProcessPrompt(request.body.messages, postProcessType, getPromptNames(request));
677682