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