Go team dropdown
| @@ -498,7 +498,3 @@ label[for="trim_spaces"]:not(:has(input:checked)) small { | |||
| 498 | #banned_tokens_block_ooba:not(:has(#send_banned_tokens_textgenerationwebui:checked)) #banned_tokens_controls_ooba { | 498 | #banned_tokens_block_ooba:not(:has(#send_banned_tokens_textgenerationwebui:checked)) #banned_tokens_controls_ooba { |
| 499 | filter: brightness(0.5); | 499 | filter: brightness(0.5); |
| 500 | } | 500 | } |
| 501 | |||
| 502 | #thinking_budget_controls:not(:has(#enable_thinking:checked)) .range-block:has(#thinking_budget) { | ||
| 503 | filter: brightness(0.5); | ||
| 504 | } | ||
| @@ -2034,32 +2034,6 @@ | |||
| 2034 | </span> | 2034 | </span> |
| 2035 | </div> | 2035 | </div> |
| 2036 | </div> | 2036 | </div> |
| 2037 | <div id="thinking_budget_container" data-source="makersuite"> | ||
| 2038 | <div id="thinking_budget_controls"> | ||
| 2039 | <div class="range-block"> | ||
| 2040 | <label for="enable_thinking" class="checkbox_label widthFreeExpand"> | ||
| 2041 | <input id="enable_thinking" type="checkbox" /> | ||
| 2042 | <span data-i18n="Enable thinking">Enable thinking</span> | ||
| 2043 | </label> | ||
| 2044 | <div class="toggle-description justifyLeft marginBot5" data-i18n="thinking_budget_desc"> | ||
| 2045 | Must be enabled for Thinking Budget to take effect. | ||
| 2046 | </div> | ||
| 2047 | </div> | ||
| 2048 | <div class="range-block"> | ||
| 2049 | <div class="range-block-title" data-i18n="Thinking Budget (Tokens)"> | ||
| 2050 | Thinking Budget (tokens) | ||
| 2051 | </div> | ||
| 2052 | <div class="range-block-range-and-counter"> | ||
| 2053 | <div class="range-block-range"> | ||
| 2054 | <input id="thinking_budget" type="range" min="0" max="24576" step="1"> | ||
| 2055 | </div> | ||
| 2056 | <div class="range-block-counter"> | ||
| 2057 | <input id="thinking_budget_counter" type="number" min="0" max="24576" step="1" data-for="thinking_budget"> | ||
| 2058 | </div> | ||
| 2059 | </div> | ||
| 2060 | </div> | ||
| 2061 | </div> | ||
| 2062 | </div> | ||
| 2063 | <div class="range-block" data-source="deepseek,openrouter,custom,claude,xai"> | 2037 | <div class="range-block" data-source="deepseek,openrouter,custom,claude,xai"> |
| 2064 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> | 2038 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> |
| 2065 | <input id="openai_show_thoughts" type="checkbox" /> | 2039 | <input id="openai_show_thoughts" type="checkbox" /> |
| @@ -2074,16 +2048,19 @@ | |||
| 2074 | </span> | 2048 | </span> |
| 2075 | </div> | 2049 | </div> |
| 2076 | </div> | 2050 | </div> |
| 2077 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai"> | 2051 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,claude,xai,makersuite"> |
| 2078 | <div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models. Currently supported values are low, medium, and high. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models."> | 2052 | <div class="flex-container oneline-dropdown" title="Constrains effort on reasoning for reasoning models. Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response." data-i18n="[title]Constrains effort on reasoning for reasoning models."> |
| 2079 | <label for="openai_reasoning_effort"> | 2053 | <label for="openai_reasoning_effort"> |
| 2080 | <span data-i18n="Reasoning Effort">Reasoning Effort</span> | 2054 | <span data-i18n="Reasoning Effort">Reasoning Effort</span> |
| 2081 | <i data-source="claude" class="opacity50p fa-solid fa-circle-info" title="Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%), but minimum 1024 tokens."></i> | 2055 | <i data-source="claude,makersuite" class="opacity50p fa-solid fa-circle-info" title="Allocates a portion of the response length for thinking (low: 10%, medium: 25%, high: 50%), but minimum 1024 tokens."></i> |
| 2082 | </label> | 2056 | </label> |
| 2083 | <select id="openai_reasoning_effort"> | 2057 | <select id="openai_reasoning_effort"> |
| 2058 | <option data-i18n="openai_reasoning_effort_auto" value="auto">Unset (model-default)</option> | ||
| 2059 | <option data-i18n="openai_reasoning_effort_minimum" value="min">Mininum (model-defined)</option> | ||
| 2084 | <option data-i18n="openai_reasoning_effort_low" value="low">Low</option> | 2060 | <option data-i18n="openai_reasoning_effort_low" value="low">Low</option> |
| 2085 | <option data-i18n="openai_reasoning_effort_medium" value="medium">Medium</option> | 2061 | <option data-i18n="openai_reasoning_effort_medium" value="medium">Medium</option> |
| 2086 | <option data-i18n="openai_reasoning_effort_high" value="high">High</option> | 2062 | <option data-i18n="openai_reasoning_effort_high" value="high">High</option> |
| 2063 | <option data-i18n="openai_reasoning_effort_maximum" value="max">Maximum (model-defined)</option> | ||
| 2087 | </select> | 2064 | </select> |
| 2088 | </div> | 2065 | </div> |
| 2089 | </div> | 2066 | </div> |
| @@ -165,11 +165,6 @@ const textCompletionModels = [ | |||
| 165 | 'code-search-ada-code-001', | 165 | 'code-search-ada-code-001', |
| 166 | ]; | 166 | ]; |
| 167 | 167 | ||
| 168 | // One more models list to maintain, yay | ||
| 169 | const thinkingBudgetModels = [ | ||
| 170 | 'gemini-2.5-flash-preview-04-17', | ||
| 171 | ]; | ||
| 172 | |||
| 173 | let biasCache = undefined; | 168 | let biasCache = undefined; |
| 174 | export let model_list = []; | 169 | export let model_list = []; |
| 175 | 170 | ||
| @@ -221,6 +216,15 @@ const openrouter_middleout_types = { | |||
| 221 | OFF: 'off', | 216 | OFF: 'off', |
| 222 | }; | 217 | }; |
| 223 | 218 | ||
| 219 | export const reasoning_effort_types = { | ||
| 220 | auto: 'auto', | ||
| 221 | low: 'low', | ||
| 222 | medium: 'medium', | ||
| 223 | high: 'high', | ||
| 224 | min: 'min', | ||
| 225 | max: 'max', | ||
| 226 | }; | ||
| 227 | |||
| 224 | const sensitiveFields = [ | 228 | const sensitiveFields = [ |
| 225 | 'reverse_proxy', | 229 | 'reverse_proxy', |
| 226 | 'proxy_password', | 230 | 'proxy_password', |
| @@ -311,8 +315,6 @@ export const settingsToUpdate = { | |||
| 311 | n: ['#n_openai', 'n', false], | 315 | n: ['#n_openai', 'n', false], |
| 312 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true], | 316 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true], |
| 313 | request_images: ['#openai_request_images', 'request_images', true], | 317 | request_images: ['#openai_request_images', 'request_images', true], |
| 314 | enable_thinking: ['#enable_thinking', 'enable_thinking', true], | ||
| 315 | thinking_budget: ['#thinking_budget', 'thinking_budget', false], | ||
| 316 | }; | 318 | }; |
| 317 | 319 | ||
| 318 | const default_settings = { | 320 | const default_settings = { |
| @@ -389,11 +391,9 @@ const default_settings = { | |||
| 389 | continue_postfix: continue_postfix_types.SPACE, | 391 | continue_postfix: continue_postfix_types.SPACE, |
| 390 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, | 392 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 391 | show_thoughts: true, | 393 | show_thoughts: true, |
| 392 | reasoning_effort: 'medium', | 394 | reasoning_effort: reasoning_effort_types.medium, |
| 393 | enable_web_search: false, | 395 | enable_web_search: false, |
| 394 | request_images: false, | 396 | request_images: false, |
| 395 | enable_thinking: true, | ||
| 396 | thinking_budget: 1000, | ||
| 397 | seed: -1, | 397 | seed: -1, |
| 398 | n: 1, | 398 | n: 1, |
| 399 | }; | 399 | }; |
| @@ -472,11 +472,9 @@ const oai_settings = { | |||
| 472 | continue_postfix: continue_postfix_types.SPACE, | 472 | continue_postfix: continue_postfix_types.SPACE, |
| 473 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, | 473 | custom_prompt_post_processing: custom_prompt_post_processing_types.NONE, |
| 474 | show_thoughts: true, | 474 | show_thoughts: true, |
| 475 | reasoning_effort: 'medium', | 475 | reasoning_effort: reasoning_effort_types.medium, |
| 476 | enable_web_search: false, | 476 | enable_web_search: false, |
| 477 | request_images: false, | 477 | request_images: false, |
| 478 | enable_thinking: true, | ||
| 479 | thinking_budget: 1000, | ||
| 480 | seed: -1, | 478 | seed: -1, |
| 481 | n: 1, | 479 | n: 1, |
| 482 | }; | 480 | }; |
| @@ -1948,6 +1946,35 @@ async function sendAltScaleRequest(messages, logit_bias, signal, type) { | |||
| 1948 | return data.output; | 1946 | return data.output; |
| 1949 | } | 1947 | } |
| 1950 | 1948 | ||
| 1949 | function getReasoningEffort() { | ||
| 1950 | // Do not set the field. Let the model decide. | ||
| 1951 | if (oai_settings.reasoning_effort === reasoning_effort_types.auto) { | ||
| 1952 | return undefined; | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | // These sources require effort as a string | ||
| 1956 | if (oai_settings.reasoning_effort === reasoning_effort_types.min) { | ||
| 1957 | switch (oai_settings.chat_completion_source) { | ||
| 1958 | case chat_completion_sources.OPENAI: | ||
| 1959 | case chat_completion_sources.CUSTOM: | ||
| 1960 | case chat_completion_sources.XAI: | ||
| 1961 | return reasoning_effort_types.low; | ||
| 1962 | } | ||
| 1963 | } | ||
| 1964 | |||
| 1965 | // Same here, but max effort | ||
| 1966 | if (oai_settings.reasoning_effort === reasoning_effort_types.max) { | ||
| 1967 | switch (oai_settings.chat_completion_source) { | ||
| 1968 | case chat_completion_sources.OPENAI: | ||
| 1969 | case chat_completion_sources.CUSTOM: | ||
| 1970 | case chat_completion_sources.XAI: | ||
| 1971 | return reasoning_effort_types.high; | ||
| 1972 | } | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | return oai_settings.reasoning_effort; | ||
| 1976 | } | ||
| 1977 | |||
| 1951 | /** | 1978 | /** |
| 1952 | * Send a chat completion request to backend | 1979 | * Send a chat completion request to backend |
| 1953 | * @param {string} type (impersonate, quiet, continue, etc) | 1980 | * @param {string} type (impersonate, quiet, continue, etc) |
| @@ -2034,17 +2061,12 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 2034 | 'char_name': name2, | 2061 | 'char_name': name2, |
| 2035 | 'group_names': getGroupNames(), | 2062 | 'group_names': getGroupNames(), |
| 2036 | 'include_reasoning': Boolean(oai_settings.show_thoughts), | 2063 | 'include_reasoning': Boolean(oai_settings.show_thoughts), |
| 2037 | 'reasoning_effort': String(oai_settings.reasoning_effort), | 2064 | 'reasoning_effort': getReasoningEffort(), |
| 2038 | 'enable_web_search': Boolean(oai_settings.enable_web_search), | 2065 | 'enable_web_search': Boolean(oai_settings.enable_web_search), |
| 2039 | 'request_images': Boolean(oai_settings.request_images), | 2066 | 'request_images': Boolean(oai_settings.request_images), |
| 2040 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, | 2067 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, |
| 2041 | }; | 2068 | }; |
| 2042 | 2069 | ||
| 2043 | if (thinkingBudgetModels.includes(model)) { | ||
| 2044 | generate_data['enable_thinking'] = oai_settings.enable_thinking; | ||
| 2045 | generate_data['thinking_budget'] = oai_settings.thinking_budget; | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) { | 2070 | if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) { |
| 2049 | await ToolManager.registerFunctionToolsOpenAI(generate_data); | 2071 | await ToolManager.registerFunctionToolsOpenAI(generate_data); |
| 2050 | } | 2072 | } |
| @@ -3300,8 +3322,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3300 | oai_settings.show_thoughts = settings.show_thoughts ?? default_settings.show_thoughts; | 3322 | oai_settings.show_thoughts = settings.show_thoughts ?? default_settings.show_thoughts; |
| 3301 | oai_settings.reasoning_effort = settings.reasoning_effort ?? default_settings.reasoning_effort; | 3323 | oai_settings.reasoning_effort = settings.reasoning_effort ?? default_settings.reasoning_effort; |
| 3302 | oai_settings.enable_web_search = settings.enable_web_search ?? default_settings.enable_web_search; | 3324 | oai_settings.enable_web_search = settings.enable_web_search ?? default_settings.enable_web_search; |
| 3303 | oai_settings.enable_thinking = settings.enable_thinking ?? default_settings.enable_thinking; | ||
| 3304 | oai_settings.thinking_budget = settings.thinking_budget ?? default_settings.thinking_budget; | ||
| 3305 | oai_settings.request_images = settings.request_images ?? default_settings.request_images; | 3325 | oai_settings.request_images = settings.request_images ?? default_settings.request_images; |
| 3306 | oai_settings.seed = settings.seed ?? default_settings.seed; | 3326 | oai_settings.seed = settings.seed ?? default_settings.seed; |
| 3307 | oai_settings.n = settings.n ?? default_settings.n; | 3327 | oai_settings.n = settings.n ?? default_settings.n; |
| @@ -3437,10 +3457,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3437 | $('#openai_reasoning_effort').val(oai_settings.reasoning_effort); | 3457 | $('#openai_reasoning_effort').val(oai_settings.reasoning_effort); |
| 3438 | $(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true); | 3458 | $(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true); |
| 3439 | 3459 | ||
| 3440 | $('#enable_thinking').prop('checked', oai_settings.enable_thinking); | ||
| 3441 | $('#thinking_budget').val(oai_settings.thinking_budget); | ||
| 3442 | $('#thinking_budget_counter').val(oai_settings.thinking_budget); | ||
| 3443 | |||
| 3444 | if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy; | 3460 | if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy; |
| 3445 | $('#openai_reverse_proxy').val(oai_settings.reverse_proxy); | 3461 | $('#openai_reverse_proxy').val(oai_settings.reverse_proxy); |
| 3446 | 3462 | ||
| @@ -3471,7 +3487,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3471 | 3487 | ||
| 3472 | setNamesBehaviorControls(); | 3488 | setNamesBehaviorControls(); |
| 3473 | setContinuePostfixControls(); | 3489 | setContinuePostfixControls(); |
| 3474 | updateThinkingBudgetUI(); | ||
| 3475 | 3490 | ||
| 3476 | if (oai_settings.custom_prompt_post_processing === custom_prompt_post_processing_types.CLAUDE) { | 3491 | if (oai_settings.custom_prompt_post_processing === custom_prompt_post_processing_types.CLAUDE) { |
| 3477 | oai_settings.custom_prompt_post_processing = custom_prompt_post_processing_types.MERGE; | 3492 | oai_settings.custom_prompt_post_processing = custom_prompt_post_processing_types.MERGE; |
| @@ -3529,14 +3544,6 @@ function setContinuePostfixControls() { | |||
| 3529 | $('#continue_postfix_display').text(checkedItemText); | 3544 | $('#continue_postfix_display').text(checkedItemText); |
| 3530 | } | 3545 | } |
| 3531 | 3546 | ||
| 3532 | /** | ||
| 3533 | * Updates the visibility and state of the Thinking Budget controls. | ||
| 3534 | */ | ||
| 3535 | function updateThinkingBudgetUI() { | ||
| 3536 | const modelSupportsControl = thinkingBudgetModels.includes(getChatCompletionModel()); | ||
| 3537 | $('#thinking_budget_controls').toggle(modelSupportsControl); | ||
| 3538 | } | ||
| 3539 | |||
| 3540 | async function getStatusOpen() { | 3547 | async function getStatusOpen() { |
| 3541 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) { | 3548 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) { |
| 3542 | let status; | 3549 | let status; |
| @@ -3717,8 +3724,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3717 | reasoning_effort: settings.reasoning_effort, | 3724 | reasoning_effort: settings.reasoning_effort, |
| 3718 | enable_web_search: settings.enable_web_search, | 3725 | enable_web_search: settings.enable_web_search, |
| 3719 | request_images: settings.request_images, | 3726 | request_images: settings.request_images, |
| 3720 | enable_thinking: settings.enable_thinking, | ||
| 3721 | thinking_budget: settings.thinking_budget, | ||
| 3722 | seed: settings.seed, | 3727 | seed: settings.seed, |
| 3723 | n: settings.n, | 3728 | n: settings.n, |
| 3724 | }; | 3729 | }; |
| @@ -4749,7 +4754,6 @@ async function onModelChange() { | |||
| 4749 | 4754 | ||
| 4750 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); | 4755 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); |
| 4751 | 4756 | ||
| 4752 | updateThinkingBudgetUI(); | ||
| 4753 | saveSettingsDebounced(); | 4757 | saveSettingsDebounced(); |
| 4754 | eventSource.emit(event_types.CHATCOMPLETION_MODEL_CHANGED, value); | 4758 | eventSource.emit(event_types.CHATCOMPLETION_MODEL_CHANGED, value); |
| 4755 | } | 4759 | } |
| @@ -5568,7 +5572,6 @@ export function initOpenAI() { | |||
| 5568 | $('#chat_completion_source').on('change', function () { | 5572 | $('#chat_completion_source').on('change', function () { |
| 5569 | oai_settings.chat_completion_source = String($(this).find(':selected').val()); | 5573 | oai_settings.chat_completion_source = String($(this).find(':selected').val()); |
| 5570 | toggleChatCompletionForms(); | 5574 | toggleChatCompletionForms(); |
| 5571 | updateThinkingBudgetUI(); | ||
| 5572 | saveSettingsDebounced(); | 5575 | saveSettingsDebounced(); |
| 5573 | reconnectOpenAi(); | 5576 | reconnectOpenAi(); |
| 5574 | forceCharacterEditorTokenize(); | 5577 | forceCharacterEditorTokenize(); |
| @@ -5754,29 +5757,6 @@ export function initOpenAI() { | |||
| 5754 | saveSettingsDebounced(); | 5757 | saveSettingsDebounced(); |
| 5755 | }); | 5758 | }); |
| 5756 | 5759 | ||
| 5757 | $('#enable_thinking').on('input', function () { | ||
| 5758 | oai_settings.enable_thinking = !!$(this).prop('checked'); | ||
| 5759 | updateThinkingBudgetUI(); | ||
| 5760 | saveSettingsDebounced(); | ||
| 5761 | }); | ||
| 5762 | |||
| 5763 | $('#thinking_budget').on('input', function () { | ||
| 5764 | oai_settings.thinking_budget = Number($(this).val()); | ||
| 5765 | $('#thinking_budget_counter').val(oai_settings.thinking_budget); | ||
| 5766 | saveSettingsDebounced(); | ||
| 5767 | }); | ||
| 5768 | |||
| 5769 | $('#thinking_budget_counter').on('input', function () { | ||
| 5770 | let value = Number($(this).val()); | ||
| 5771 | const min = Number($('#thinking_budget').attr('min')); | ||
| 5772 | const max = Number($('#thinking_budget').attr('max')); | ||
| 5773 | value = Math.max(min, Math.min(max, value)); | ||
| 5774 | $(this).val(value); | ||
| 5775 | oai_settings.thinking_budget = value; | ||
| 5776 | $('#thinking_budget').val(value); | ||
| 5777 | saveSettingsDebounced(); | ||
| 5778 | }); | ||
| 5779 | |||
| 5780 | $('#openai_enable_web_search').on('input', function () { | 5760 | $('#openai_enable_web_search').on('input', function () { |
| 5781 | oai_settings.enable_web_search = !!$(this).prop('checked'); | 5761 | oai_settings.enable_web_search = !!$(this).prop('checked'); |
| 5782 | calculateOpenRouterCost(); | 5762 | calculateOpenRouterCost(); |
| @@ -28,7 +28,8 @@ import { | |||
| 28 | cachingAtDepthForOpenRouterClaude, | 28 | cachingAtDepthForOpenRouterClaude, |
| 29 | cachingAtDepthForClaude, | 29 | cachingAtDepthForClaude, |
| 30 | getPromptNames, | 30 | getPromptNames, |
| 31 | calculateBudgetTokens, | 31 | calculateClaudeBudgetTokens, |
| 32 | calculateGoogleBudgetTokens, | ||
| 32 | } from '../../prompt-converters.js'; | 33 | } from '../../prompt-converters.js'; |
| 33 | 34 | ||
| 34 | import { readSecret, SECRET_KEYS } from '../secrets.js'; | 35 | import { readSecret, SECRET_KEYS } from '../secrets.js'; |
| @@ -202,7 +203,7 @@ async function sendClaudeRequest(request, response) { | |||
| 202 | // No prefill when thinking | 203 | // No prefill when thinking |
| 203 | voidPrefill = true; | 204 | voidPrefill = true; |
| 204 | const reasoningEffort = request.body.reasoning_effort; | 205 | const reasoningEffort = request.body.reasoning_effort; |
| 205 | const budgetTokens = calculateBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream); | 206 | const budgetTokens = calculateClaudeBudgetTokens(requestBody.max_tokens, reasoningEffort, requestBody.stream); |
| 206 | const minThinkTokens = 1024; | 207 | const minThinkTokens = 1024; |
| 207 | if (requestBody.max_tokens <= minThinkTokens) { | 208 | if (requestBody.max_tokens <= minThinkTokens) { |
| 208 | const newValue = requestBody.max_tokens + minThinkTokens; | 209 | const newValue = requestBody.max_tokens + minThinkTokens; |
| @@ -340,6 +341,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 340 | const stream = Boolean(request.body.stream); | 341 | const stream = Boolean(request.body.stream); |
| 341 | const enableWebSearch = Boolean(request.body.enable_web_search); | 342 | const enableWebSearch = Boolean(request.body.enable_web_search); |
| 342 | const requestImages = Boolean(request.body.request_images); | 343 | const requestImages = Boolean(request.body.request_images); |
| 344 | const reasoningEffort = String(request.body.reasoning_effort); | ||
| 343 | const isThinking = model.includes('thinking'); | 345 | const isThinking = model.includes('thinking'); |
| 344 | const isGemma = model.includes('gemma'); | 346 | const isGemma = model.includes('gemma'); |
| 345 | 347 | ||
| @@ -412,11 +414,15 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 412 | tools.push({ function_declarations: functionDeclarations }); | 414 | tools.push({ function_declarations: functionDeclarations }); |
| 413 | } | 415 | } |
| 414 | 416 | ||
| 415 | if ('enable_thinking' in request.body && 'thinking_budget' in request.body) { | 417 | // One more models list to maintain, yay |
| 416 | const thinkingEnabled = Boolean(request.body.enable_thinking); | 418 | const thinkingBudgetModels = [ |
| 417 | const thinkingBudget = Number(request.body.thinking_budget); | 419 | 'gemini-2.5-flash-preview-04-17', |
| 420 | ]; | ||
| 418 | 421 | ||
| 419 | if (thinkingEnabled) { | 422 | if (thinkingBudgetModels.includes(model)) { |
| 423 | const thinkingBudget = calculateGoogleBudgetTokens(generationConfig.maxOutputTokens, reasoningEffort); | ||
| 424 | |||
| 425 | if (Number.isInteger(thinkingBudget)) { | ||
| 420 | generationConfig.thinkingConfig = { thinkingBudget: thinkingBudget }; | 426 | generationConfig.thinkingConfig = { thinkingBudget: thinkingBudget }; |
| 421 | } | 427 | } |
| 422 | } | 428 | } |
| @@ -3,6 +3,15 @@ import { getConfigValue, tryParse } from './util.js'; | |||
| 3 | 3 | ||
| 4 | const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.'); | 4 | const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.'); |
| 5 | 5 | ||
| 6 | const REASONING_EFFORT = { | ||
| 7 | auto: 'auto', | ||
| 8 | low: 'low', | ||
| 9 | medium: 'medium', | ||
| 10 | high: 'high', | ||
| 11 | min: 'min', | ||
| 12 | max: 'max', | ||
| 13 | }; | ||
| 14 | |||
| 6 | /** | 15 | /** |
| 7 | * @typedef {object} PromptNames | 16 | * @typedef {object} PromptNames |
| 8 | * @property {string} charName Character name | 17 | * @property {string} charName Character name |
| @@ -944,25 +953,35 @@ export function cachingAtDepthForOpenRouterClaude(messages, cachingAtDepth) { | |||
| 944 | } | 953 | } |
| 945 | 954 | ||
| 946 | /** | 955 | /** |
| 947 | * Calculate the budget tokens for a given reasoning effort. | 956 | * Calculate the Claude budget tokens for a given reasoning effort. |
| 948 | * @param {number} maxTokens Maximum tokens | 957 | * @param {number} maxTokens Maximum tokens |
| 949 | * @param {string} reasoningEffort Reasoning effort | 958 | * @param {string} reasoningEffort Reasoning effort |
| 950 | * @param {boolean} stream If streaming is enabled | 959 | * @param {boolean} stream If streaming is enabled |
| 951 | * @returns {number} Budget tokens | 960 | * @returns {number} Budget tokens |
| 952 | */ | 961 | */ |
| 953 | export function calculateBudgetTokens(maxTokens, reasoningEffort, stream) { | 962 | export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream) { |
| 954 | let budgetTokens = 0; | 963 | let budgetTokens = 0; |
| 955 | 964 | ||
| 956 | switch (reasoningEffort) { | 965 | switch (reasoningEffort) { |
| 957 | case 'low': | 966 | // Claude doesn't have a default budget value. Use same as min. |
| 967 | case REASONING_EFFORT.auto: | ||
| 968 | budgetTokens = 1024; | ||
| 969 | break; | ||
| 970 | case REASONING_EFFORT.min: | ||
| 971 | budgetTokens = 1024; | ||
| 972 | break; | ||
| 973 | case REASONING_EFFORT.low: | ||
| 958 | budgetTokens = Math.floor(maxTokens * 0.1); | 974 | budgetTokens = Math.floor(maxTokens * 0.1); |
| 959 | break; | 975 | break; |
| 960 | case 'medium': | 976 | case REASONING_EFFORT.medium: |
| 961 | budgetTokens = Math.floor(maxTokens * 0.25); | 977 | budgetTokens = Math.floor(maxTokens * 0.25); |
| 962 | break; | 978 | break; |
| 963 | case 'high': | 979 | case REASONING_EFFORT.high: |
| 964 | budgetTokens = Math.floor(maxTokens * 0.5); | 980 | budgetTokens = Math.floor(maxTokens * 0.5); |
| 965 | break; | 981 | break; |
| 982 | case REASONING_EFFORT.max: | ||
| 983 | budgetTokens = maxTokens; | ||
| 984 | break; | ||
| 966 | } | 985 | } |
| 967 | 986 | ||
| 968 | budgetTokens = Math.max(budgetTokens, 1024); | 987 | budgetTokens = Math.max(budgetTokens, 1024); |
| @@ -973,3 +992,37 @@ export function calculateBudgetTokens(maxTokens, reasoningEffort, stream) { | |||
| 973 | 992 | ||
| 974 | return budgetTokens; | 993 | return budgetTokens; |
| 975 | } | 994 | } |
| 995 | |||
| 996 | /** | ||
| 997 | * Calculate the Google budget tokens for a given reasoning effort. | ||
| 998 | * @param {number} maxTokens Maximum tokens | ||
| 999 | * @param {string} reasoningEffort Reasoning effort | ||
| 1000 | * @returns {number?} Budget tokens | ||
| 1001 | */ | ||
| 1002 | export function calculateGoogleBudgetTokens(maxTokens, reasoningEffort) { | ||
| 1003 | let budgetTokens = 0; | ||
| 1004 | |||
| 1005 | switch (reasoningEffort) { | ||
| 1006 | case REASONING_EFFORT.auto: | ||
| 1007 | return null; | ||
| 1008 | case REASONING_EFFORT.min: | ||
| 1009 | budgetTokens = 0; | ||
| 1010 | break; | ||
| 1011 | case REASONING_EFFORT.low: | ||
| 1012 | budgetTokens = Math.floor(maxTokens * 0.1); | ||
| 1013 | break; | ||
| 1014 | case REASONING_EFFORT.medium: | ||
| 1015 | budgetTokens = Math.floor(maxTokens * 0.25); | ||
| 1016 | break; | ||
| 1017 | case REASONING_EFFORT.high: | ||
| 1018 | budgetTokens = Math.floor(maxTokens * 0.5); | ||
| 1019 | break; | ||
| 1020 | case REASONING_EFFORT.max: | ||
| 1021 | budgetTokens = maxTokens; | ||
| 1022 | break; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | budgetTokens = Math.min(budgetTokens, 24576); | ||
| 1026 | |||
| 1027 | return budgetTokens; | ||
| 1028 | } | ||