Merge pull request #3396 from pcpthm/text-completion-include-reasoning Support reasoning for OpenRouter Text Completion
Signed| @@ -1587,6 +1587,10 @@ | ||
| 1587 | 1587 | <input type="checkbox" id="skip_special_tokens_textgenerationwebui" /> |
| 1588 | 1588 | <small data-i18n="Skip Special Tokens">Skip Special Tokens</small> |
| 1589 | 1589 | </label> |
| 1590 | + <label data-tg-type="openrouter" class="checkbox_label flexGrow flexShrink" for="include_reasoning_textgenerationwebui"> | |
| 1591 | + <input type="checkbox" id="include_reasoning_textgenerationwebui" /> | |
| 1592 | + <small data-i18n="Request Model Reasoning">Request Model Reasoning</small> | |
| 1593 | + </label> | |
| 1590 | 1594 | <label data-tg-type="ooba, aphrodite, tabby" class="checkbox_label flexGrow flexShrink" for="temperature_last_textgenerationwebui"> |
| 1591 | 1595 | <input type="checkbox" id="temperature_last_textgenerationwebui" /> |
| 1592 | 1596 | <label> |
| @@ -5706,7 +5706,17 @@ function extractMessageFromData(data) { | ||
| 5706 | 5706 | * @returns {string} Extracted reasoning |
| 5707 | 5707 | */ |
| 5708 | 5708 | function extractReasoningFromData(data) { |
| 5709 | - if (main_api === 'openai' && oai_settings.show_thoughts) { | |
| 5709 | + switch (main_api) { | |
| 5710 | + case 'textgenerationwebui': | |
| 5711 | + switch (textgen_settings.type) { | |
| 5712 | + case textgen_types.OPENROUTER: | |
| 5713 | + return data?.choices?.[0]?.reasoning ?? ''; | |
| 5714 | + } | |
| 5715 | + break; | |
| 5716 | + | |
| 5717 | + case 'openai': | |
| 5718 | + if (!oai_settings.show_thoughts) break; | |
| 5719 | + | |
| 5710 | 5720 | switch (oai_settings.chat_completion_source) { |
| 5711 | 5721 | case chat_completion_sources.DEEPSEEK: |
| 5712 | 5722 | return data?.choices?.[0]?.message?.reasoning_content ?? ''; |
| @@ -5715,6 +5725,7 @@ function extractReasoningFromData(data) { | ||
| 5715 | 5725 | case chat_completion_sources.MAKERSUITE: |
| 5716 | 5726 | return data?.responseContent?.parts?.filter(part => part.thought)?.map(part => part.text)?.join('\n\n') ?? ''; |
| 5717 | 5727 | } |
| 5728 | + break; | |
| 5718 | 5729 | } |
| 5719 | 5730 | |
| 5720 | 5731 | return ''; |
| @@ -298,7 +298,7 @@ const default_settings = { | ||
| 298 | 298 | names_behavior: character_names_behavior.DEFAULT, |
| 299 | 299 | continue_postfix: continue_postfix_types.SPACE, |
| 300 | 300 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 301 | 301 | show_thoughts: falsetrue, |
| 302 | 302 | seed: -1, |
| 303 | 303 | n: 1, |
| 304 | 304 | }; |
| @@ -377,7 +377,7 @@ const oai_settings = { | ||
| 377 | 377 | names_behavior: character_names_behavior.DEFAULT, |
| 378 | 378 | continue_postfix: continue_postfix_types.SPACE, |
| 379 | 379 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 380 | 380 | show_thoughts: falsetrue, |
| 381 | 381 | seed: -1, |
| 382 | 382 | n: 1, |
| 383 | 383 | }; |
| @@ -1913,7 +1913,7 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1913 | 1913 | 'user_name': name1, |
| 1914 | 1914 | 'char_name': name2, |
| 1915 | 1915 | 'group_names': getGroupNames(), |
| 1916 | 1916 | 'show_thoughtsinclude_reasoning': Boolean(oai_settings.show_thoughts), |
| 1917 | 1917 | }; |
| 1918 | 1918 | |
| 1919 | 1919 | // Empty array will produce a validation error |
| @@ -586,6 +586,7 @@ class PresetManager { | ||
| 586 | 586 | 'tabby_model', |
| 587 | 587 | 'derived', |
| 588 | 588 | 'generic_model', |
| 589 | + 'include_reasoning', | |
| 589 | 590 | ]; |
| 590 | 591 | const settings = Object.assign({}, getSettingsByApiId(this.apiId)); |
| 591 | 592 | |
| @@ -172,6 +172,7 @@ const settings = { | ||
| 172 | 172 | //truncation_length: 2048, |
| 173 | 173 | ban_eos_token: false, |
| 174 | 174 | skip_special_tokens: true, |
| 175 | + include_reasoning: true, | |
| 175 | 176 | streaming: false, |
| 176 | 177 | mirostat_mode: 0, |
| 177 | 178 | mirostat_tau: 5, |
| @@ -263,6 +264,7 @@ export const setting_names = [ | ||
| 263 | 264 | 'add_bos_token', |
| 264 | 265 | 'ban_eos_token', |
| 265 | 266 | 'skip_special_tokens', |
| 267 | + 'include_reasoning', | |
| 266 | 268 | 'streaming', |
| 267 | 269 | 'mirostat_mode', |
| 268 | 270 | 'mirostat_tau', |
| @@ -740,6 +742,7 @@ jQuery(function () { | ||
| 740 | 742 | 'add_bos_token_textgenerationwebui': true, |
| 741 | 743 | 'temperature_last_textgenerationwebui': true, |
| 742 | 744 | 'skip_special_tokens_textgenerationwebui': true, |
| 745 | + 'include_reasoning_textgenerationwebui': true, | |
| 743 | 746 | 'top_a_textgenerationwebui': 0, |
| 744 | 747 | 'top_a_counter_textgenerationwebui': 0, |
| 745 | 748 | 'mirostat_mode_textgenerationwebui': 0, |
| @@ -986,7 +989,7 @@ export async function generateTextGenWithStreaming(generate_data, signal) { | ||
| 986 | 989 | let logprobs = null; |
| 987 | 990 | const swipes = []; |
| 988 | 991 | const toolCalls = []; |
| 989 | 992 | const state = { reasoning: '' }; |
| 990 | 993 | while (true) { |
| 991 | 994 | const { done, value } = await reader.read(); |
| 992 | 995 | if (done) return; |
| @@ -1003,6 +1006,7 @@ export async function generateTextGenWithStreaming(generate_data, signal) { | ||
| 1003 | 1006 | const newText = data?.choices?.[0]?.text || data?.content || ''; |
| 1004 | 1007 | text += newText; |
| 1005 | 1008 | logprobs = parseTextgenLogprobs(newText, data.choices?.[0]?.logprobs || data?.completion_probabilities); |
| 1009 | + state.reasoning += data?.choices?.[0]?.reasoning ?? ''; | |
| 1006 | 1010 | } |
| 1007 | 1011 | |
| 1008 | 1012 | yield { text, swipes, logprobs, toolCalls, state }; |
| @@ -1266,6 +1270,7 @@ export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate, | ||
| 1266 | 1270 | 'truncation_length': max_context, |
| 1267 | 1271 | 'ban_eos_token': settings.ban_eos_token, |
| 1268 | 1272 | 'skip_special_tokens': settings.skip_special_tokens, |
| 1273 | + 'include_reasoning': settings.include_reasoning, | |
| 1269 | 1274 | 'top_a': settings.top_a, |
| 1270 | 1275 | 'tfs': settings.tfs, |
| 1271 | 1276 | 'epsilon_cutoff': [OOBA, MANCER].includes(settings.type) ? settings.epsilon_cutoff : undefined, |
| @@ -369,6 +369,7 @@ export const OPENROUTER_KEYS = [ | ||
| 369 | 369 | 'prompt', |
| 370 | 370 | 'stop', |
| 371 | 371 | 'provider', |
| 372 | + 'include_reasoning', | |
| 372 | 373 | ]; |
| 373 | 374 | |
| 374 | 375 | // https://github.com/vllm-project/vllm/blob/0f8a91401c89ac0a8018def3756829611b57727f/vllm/entrypoints/openai/protocol.py#L220 |
| @@ -288,7 +288,7 @@ async function sendMakerSuiteRequest(request, response) { | ||
| 288 | 288 | |
| 289 | 289 | const model = String(request.body.model); |
| 290 | 290 | const stream = Boolean(request.body.stream); |
| 291 | 291 | const showThoughts = Boolean(request.body.show_thoughtsinclude_reasoning); |
| 292 | 292 | const isThinking = model.includes('thinking'); |
| 293 | 293 | |
| 294 | 294 | const generationConfig = { |
| @@ -998,7 +998,7 @@ router.post('/generate', jsonParser, function (request, response) { | ||
| 998 | 998 | bodyParams['route'] = 'fallback'; |
| 999 | 999 | } |
| 1000 | 1000 | |
| 1001 | 1001 | if (request.body.show_thoughtsinclude_reasoning) { |
| 1002 | 1002 | bodyParams['include_reasoning'] = true; |
| 1003 | 1003 | } |
| 1004 | 1004 | |