feat(openrouter): disable reasoning if Request model reasoning is off and effort is minimum (#5079) * feat(openrouter): disable reasoning if "Request model reasoning" is disabled * feat(openrouter): map minimum reasoning to none if request reasoning is off * Add hint how to disable reasoning --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -2129,7 +2129,7 @@ | |||
| 2129 | <span data-i18n="Allows the model to return its thinking process."> | 2129 | <span data-i18n="Allows the model to return its thinking process."> |
| 2130 | Allows the model to return its thinking process. | 2130 | Allows the model to return its thinking process. |
| 2131 | </span> | 2131 | </span> |
| 2132 | <strong data-i18n="This setting affects visibility only." data-source-mode="except" data-source="zai,moonshot"> | 2132 | <strong data-i18n="This setting affects visibility only." data-source-mode="except" data-source="zai,moonshot,openrouter"> |
| 2133 | This setting affects visibility only. | 2133 | This setting affects visibility only. |
| 2134 | </strong> | 2134 | </strong> |
| 2135 | </div> | 2135 | </div> |
| @@ -2151,6 +2151,9 @@ | |||
| 2151 | <div class="toggle-description justifyLeft marginBot5" data-source="openai,custom,xai,aimlapi,openrouter,pollinations,perplexity,cometapi,electronhub,azure_openai,chutes" data-i18n="OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level."> | 2151 | <div class="toggle-description justifyLeft marginBot5" data-source="openai,custom,xai,aimlapi,openrouter,pollinations,perplexity,cometapi,electronhub,azure_openai,chutes" data-i18n="OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level."> |
| 2152 | OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level. | 2152 | OpenAI-style options: low, medium, high. Minimum and maximum are aliased to low and high. Auto does not send an effort level. |
| 2153 | </div> | 2153 | </div> |
| 2154 | <strong class="toggle-description justifyLeft marginBot5" data-source="openrouter"> | ||
| 2155 | Request model reasoning = Off with Reasoning Effort = Minimum disables reasoning entirely on models that support that, but can cause errors with some models. | ||
| 2156 | </strong> | ||
| 2154 | <div class="toggle-description justifyLeft marginBot5" data-source="claude" data-i18n="Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking."> | 2157 | <div class="toggle-description justifyLeft marginBot5" data-source="claude" data-i18n="Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking."> |
| 2155 | Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking. | 2158 | Allocates a portion of the response length for thinking (min: 1024 tokens, low: 10%, medium: 25%, high: 50%, max: 95%), but minimum 1024 tokens. Auto does not request thinking. |
| 2156 | </div> | 2159 | </div> |
| @@ -2462,6 +2462,10 @@ function getReasoningEffort(settings = null, model = null) { | |||
| 2462 | case reasoning_effort_types.auto: | 2462 | case reasoning_effort_types.auto: |
| 2463 | return undefined; | 2463 | return undefined; |
| 2464 | case reasoning_effort_types.min: | 2464 | case reasoning_effort_types.min: |
| 2465 | if (chat_completion_sources.OPENROUTER === settings.chat_completion_source && !settings.show_thoughts) { | ||
| 2466 | return 'none'; | ||
| 2467 | } | ||
| 2468 | |||
| 2465 | return [chat_completion_sources.OPENAI, chat_completion_sources.AZURE_OPENAI].includes(settings.chat_completion_source) && /^gpt-5/.test(model) | 2469 | return [chat_completion_sources.OPENAI, chat_completion_sources.AZURE_OPENAI].includes(settings.chat_completion_source) && /^gpt-5/.test(model) |
| 2466 | ? reasoning_effort_types.min | 2470 | ? reasoning_effort_types.min |
| 2467 | : reasoning_effort_types.low; | 2471 | : reasoning_effort_types.low; |
| @@ -2070,10 +2070,13 @@ router.post('/generate', async function (request, response) { | |||
| 2070 | apiKey = readSecret(request.user.directories, SECRET_KEYS.OPENROUTER); | 2070 | apiKey = readSecret(request.user.directories, SECRET_KEYS.OPENROUTER); |
| 2071 | // OpenRouter needs to pass the Referer and X-Title: https://openrouter.ai/docs#requests | 2071 | // OpenRouter needs to pass the Referer and X-Title: https://openrouter.ai/docs#requests |
| 2072 | headers = { ...OPENROUTER_HEADERS }; | 2072 | headers = { ...OPENROUTER_HEADERS }; |
| 2073 | const includeReasoning = Boolean(request.body.include_reasoning); | ||
| 2073 | bodyParams = { | 2074 | bodyParams = { |
| 2074 | 'transforms': getOpenRouterTransforms(request), | 2075 | transforms: getOpenRouterTransforms(request), |
| 2075 | 'plugins': getOpenRouterPlugins(request), | 2076 | plugins: getOpenRouterPlugins(request), |
| 2076 | 'include_reasoning': Boolean(request.body.include_reasoning), | 2077 | reasoning: { |
| 2078 | exclude: !includeReasoning, | ||
| 2079 | }, | ||
| 2077 | }; | 2080 | }; |
| 2078 | 2081 | ||
| 2079 | if (request.body.min_p !== undefined) { | 2082 | if (request.body.min_p !== undefined) { |
| @@ -2105,7 +2108,7 @@ router.post('/generate', async function (request, response) { | |||
| 2105 | } | 2108 | } |
| 2106 | 2109 | ||
| 2107 | if (request.body.reasoning_effort) { | 2110 | if (request.body.reasoning_effort) { |
| 2108 | bodyParams['reasoning'] = { effort: request.body.reasoning_effort }; | 2111 | bodyParams['reasoning']['effort'] = request.body.reasoning_effort; |
| 2109 | } | 2112 | } |
| 2110 | 2113 | ||
| 2111 | if (request.body.verbosity) { | 2114 | if (request.body.verbosity) { |