Better thonk effort for Gem 3

83ea6e5cbf20f919c3d5add2ec65cfdd9faf2197

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

3 files changed, +63 -7Ignore whitespace
public/index.html+8 -2
@@ -2108,8 +2108,14 @@
2108 <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.">2108 <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.">
2109 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.2109 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.
2110 </div>2110 </div>
2111 <div class="toggle-description justifyLeft marginBot5" data-source="makersuite,vertexai" data-i18n="Allocates a portion of the response length for thinking (Flash 2.5/Pro 2.5) (min: 0/128 tokens, low: 10%, medium: 25%, high: 50%, max: 24576/32768 tokens). Auto lets the model decide.">2111 <div class="toggle-description justifyLeft marginBot5" data-source="makersuite,vertexai">
2112 Allocates a portion of the response length for thinking (Flash 2.5/Pro 2.5) (min: 0/128 tokens, low: 10%, medium: 25%, high: 50%, max: 24576/32768 tokens). Auto lets the model decide.2112 <span data-i18n="Sets a dynamic reasoning depth level for thinking (Flash 3/Pro 3). High and low are supported by both, minimal and medium are Flash 3 only. Auto lets the model decide.">
2113 Sets a dynamic reasoning depth level for thinking (Flash 3/Pro 3). High and low are supported by both, minimal and medium are Flash 3 only. Auto lets the model decide.
2114 </span>
2115 <br>
2116 <span data-i18n="Allocates a portion of the response length for thinking (Flash 2.5/Pro 2.5) (min: 0/128 tokens, low: 10%, medium: 25%, high: 50%, max: 24576/32768 tokens). Auto lets the model decide.">
2117 Allocates a portion of the response length for thinking (Flash 2.5/Pro 2.5) (min: 0/128 tokens, low: 10%, medium: 25%, high: 50%, max: 24576/32768 tokens). Auto lets the model decide.
2118 </span>
2113 </div>2119 </div>
2114 </div>2120 </div>
2115 </div>2121 </div>
src/endpoints/backends/chat-completions.js+5 -1
@@ -474,10 +474,14 @@ async function sendMakerSuiteRequest(request, response) {
474 const thinkingConfig = { includeThoughts: includeReasoning };474 const thinkingConfig = { includeThoughts: includeReasoning };
475475
476 const thinkingBudget = calculateGoogleBudgetTokens(generationConfig.maxOutputTokens, reasoningEffort, model);476 const thinkingBudget = calculateGoogleBudgetTokens(generationConfig.maxOutputTokens, reasoningEffort, model);
477 if (Number.isInteger(thinkingBudget)) {477 if (typeof thinkingBudget === 'number' && Number.isInteger(thinkingBudget)) {
478 thinkingConfig.thinkingBudget = thinkingBudget;478 thinkingConfig.thinkingBudget = thinkingBudget;
479 }479 }
480480
481 if (typeof thinkingBudget === 'string' && thinkingBudget.length > 0) {
482 thinkingConfig.thinkingLevel = thinkingBudget;
483 }
484
481 // Vertex doesn't allow mixing disabled thinking with includeThoughts485 // Vertex doesn't allow mixing disabled thinking with includeThoughts
482 if (useVertexAi && thinkingBudget === 0 && thinkingConfig.includeThoughts) {486 if (useVertexAi && thinkingBudget === 0 && thinkingConfig.includeThoughts) {
483 console.info('Thinking budget is 0, but includeThoughts is true. Thoughts will not be included in the response.');487 console.info('Thinking budget is 0, but includeThoughts is true. Thoughts will not be included in the response.');
src/prompt-converters.js+50 -4
@@ -1145,7 +1145,7 @@ export function calculateClaudeBudgetTokens(maxTokens, reasoningEffort, stream)
1145 * @param {number} maxTokens Maximum tokens1145 * @param {number} maxTokens Maximum tokens
1146 * @param {string} reasoningEffort Reasoning effort1146 * @param {string} reasoningEffort Reasoning effort
1147 * @param {string} model Model name1147 * @param {string} model Model name
1148 * @returns {number?} Budget tokens1148 * @returns {number|string|null} Budget tokens
1149 */1149 */
1150export function calculateGoogleBudgetTokens(maxTokens, reasoningEffort, model) {1150export function calculateGoogleBudgetTokens(maxTokens, reasoningEffort, model) {
1151 function getFlashBudget() {1151 function getFlashBudget() {
@@ -1230,15 +1230,61 @@ export function calculateGoogleBudgetTokens(maxTokens, reasoningEffort, model) {
1230 return budgetTokens;1230 return budgetTokens;
1231 }1231 }
12321232
1233 if (model.includes('flash-lite')) {1233 function getGemini3FlashBudget() {
1234 switch (reasoningEffort) {
1235 case REASONING_EFFORT.auto:
1236 return null;
1237 case REASONING_EFFORT.min:
1238 return 'minimal';
1239 case REASONING_EFFORT.low:
1240 return 'low';
1241 case REASONING_EFFORT.medium:
1242 return 'medium';
1243 case REASONING_EFFORT.high:
1244 return 'high';
1245 case REASONING_EFFORT.max:
1246 return 'high';
1247 }
1248
1249 return null;
1250 }
1251
1252 function getGemini3ProBudget() {
1253 switch (reasoningEffort) {
1254 case REASONING_EFFORT.auto:
1255 return null;
1256 case REASONING_EFFORT.min:
1257 return 'low';
1258 case REASONING_EFFORT.low:
1259 return 'low';
1260 case REASONING_EFFORT.medium:
1261 return 'low';
1262 case REASONING_EFFORT.high:
1263 return 'high';
1264 case REASONING_EFFORT.max:
1265 return 'high';
1266 }
1267
1268 return null;
1269 }
1270
1271 if (/gemini-3-pro/.test(model)) {
1272 return getGemini3ProBudget();
1273 }
1274
1275 if (/gemini-3-flash/.test(model) ) {
1276 return getGemini3FlashBudget();
1277 }
1278
1279 if (/flash-lite/.test(model)) {
1234 return getFlashLiteBudget();1280 return getFlashLiteBudget();
1235 }1281 }
12361282
1237 if (model.includes('flash')) {1283 if (/flash/.test(model)) {
1238 return getFlashBudget();1284 return getFlashBudget();
1239 }1285 }
12401286
1241 if (model.includes('pro')) {1287 if (/pro/.test(model)) {
1242 return getProBudget();1288 return getProBudget();
1243 }1289 }
12441290