Go team dropdown

bee3cee7407df75a3a1ed80d3ca69cbeb5d33a1e

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

5 files changed, +117 -105Showing whitespace changes
public/css/toggle-dependent.css+0 -4
@@ -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}
public/index.html+6 -29
@@ -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.&#10;Currently supported values are low, medium, and high.&#10;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.&#10;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>
public/scripts/openai.js+41 -61
@@ -165,11 +165,6 @@ const textCompletionModels = [
165 'code-search-ada-code-001',165 'code-search-ada-code-001',
166];166];
167167
168// One more models list to maintain, yay
169const thinkingBudgetModels = [
170 'gemini-2.5-flash-preview-04-17',
171];
172
173let biasCache = undefined;168let biasCache = undefined;
174export let model_list = [];169export let model_list = [];
175170
@@ -221,6 +216,15 @@ const openrouter_middleout_types = {
221 OFF: 'off',216 OFF: 'off',
222};217};
223218
219export const reasoning_effort_types = {
220 auto: 'auto',
221 low: 'low',
222 medium: 'medium',
223 high: 'high',
224 min: 'min',
225 max: 'max',
226};
227
224const sensitiveFields = [228const 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};
317319
318const default_settings = {320const 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}
19501948
1949function 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 backend1979 * 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 };
20422069
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);
34393459
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);
34463462
@@ -3471,7 +3487,6 @@ function loadOpenAISettings(data, settings) {
34713487
3472 setNamesBehaviorControls();3488 setNamesBehaviorControls();
3473 setContinuePostfixControls();3489 setContinuePostfixControls();
3474 updateThinkingBudgetUI();
34753490
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}
35313546
3532/**
3533 * Updates the visibility and state of the Thinking Budget controls.
3534 */
3535function updateThinkingBudgetUI() {
3536 const modelSupportsControl = thinkingBudgetModels.includes(getChatCompletionModel());
3537 $('#thinking_budget_controls').toggle(modelSupportsControl);
3538}
3539
3540async function getStatusOpen() {3547async 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() {
47494754
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')));
47514756
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 });
57565759
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();
src/endpoints/backends/chat-completions.js+12 -6
@@ -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';
3334
34import { readSecret, SECRET_KEYS } from '../secrets.js';35import { readSecret, SECRET_KEYS } from '../secrets.js';
@@ -202,7 +203,7 @@ async function sendClaudeRequest(request, response) {
202 // No prefill when thinking203 // 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');
345347
@@ -412,11 +414,15 @@ async function sendMakerSuiteRequest(request, response) {
412 tools.push({ function_declarations: functionDeclarations });414 tools.push({ function_declarations: functionDeclarations });
413 }415 }
414416
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 ];
418421
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 }
src/prompt-converters.js+58 -5
@@ -3,6 +3,15 @@ import { getConfigValue, tryParse } from './util.js';
33
4const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.');4const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.');
55
6const 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} PromptNames16 * @typedef {object} PromptNames
8 * @property {string} charName Character name17 * @property {string} charName Character name
@@ -944,25 +953,35 @@ export function cachingAtDepthForOpenRouterClaude(messages, cachingAtDepth) {
944}953}
945954
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 tokens957 * @param {number} maxTokens Maximum tokens
949 * @param {string} reasoningEffort Reasoning effort958 * @param {string} reasoningEffort Reasoning effort
950 * @param {boolean} stream If streaming is enabled959 * @param {boolean} stream If streaming is enabled
951 * @returns {number} Budget tokens960 * @returns {number} Budget tokens
952 */961 */
953export function calculateBudgetTokens(maxTokens, reasoningEffort, stream) {962export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream) {
954 let budgetTokens = 0;963 let budgetTokens = 0;
955964
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 }
967986
968 budgetTokens = Math.max(budgetTokens, 1024);987 budgetTokens = Math.max(budgetTokens, 1024);
@@ -973,3 +992,37 @@ export function calculateBudgetTokens(maxTokens, reasoningEffort, stream) {
973992
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 */
1002export 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}