Gemini: Add image request settings (#4838) * Gemini: Add image request settings * Allow aspect ratio for 2.5 flash
Signed| @@ -563,3 +563,7 @@ label[for="bind_preset_to_connection"]:has(input:checked) { | |||
| 563 | filter: grayscale(0.5); | 563 | filter: grayscale(0.5); |
| 564 | cursor: not-allowed; | 564 | cursor: not-allowed; |
| 565 | } | 565 | } |
| 566 | |||
| 567 | #request_images_block:has(#openai_request_images:not(:checked)) #request_images_settings { | ||
| 568 | display: none; | ||
| 569 | } | ||
| @@ -2022,7 +2022,7 @@ | |||
| 2022 | </div> | 2022 | </div> |
| 2023 | </div> | 2023 | </div> |
| 2024 | </div> | 2024 | </div> |
| 2025 | <div class="range-block" data-source="makersuite,vertexai"> | 2025 | <div id="request_images_block" class="range-block" data-source="makersuite,vertexai"> |
| 2026 | <label for="openai_request_images" class="checkbox_label widthFreeExpand"> | 2026 | <label for="openai_request_images" class="checkbox_label widthFreeExpand"> |
| 2027 | <input id="openai_request_images" type="checkbox" /> | 2027 | <input id="openai_request_images" type="checkbox" /> |
| 2028 | <span> | 2028 | <span> |
| @@ -2038,6 +2038,37 @@ | |||
| 2038 | Incompatible with the following features: function calling, web search, system prompt. | 2038 | Incompatible with the following features: function calling, web search, system prompt. |
| 2039 | </em> | 2039 | </em> |
| 2040 | </div> | 2040 | </div> |
| 2041 | <div id="request_images_settings" class="flex-container wide100p textAlignCenter"> | ||
| 2042 | <div class="flex1"> | ||
| 2043 | <label for="request_image_resolution"> | ||
| 2044 | <small data-i18n="Resolution">Resolution</small> | ||
| 2045 | </label> | ||
| 2046 | <select id="request_image_resolution" class="text_pole"> | ||
| 2047 | <option value="">Auto</option> | ||
| 2048 | <option value="1K">1K</option> | ||
| 2049 | <option value="2K">2K</option> | ||
| 2050 | <option value="4K">4K</option> | ||
| 2051 | </select> | ||
| 2052 | </div> | ||
| 2053 | <div class="flex1"> | ||
| 2054 | <label for="request_image_aspect_ratio"> | ||
| 2055 | <small data-i18n="Aspect Ratio">Aspect Ratio</small> | ||
| 2056 | </label> | ||
| 2057 | <select id="request_image_aspect_ratio" class="text_pole"> | ||
| 2058 | <option value="">Auto</option> | ||
| 2059 | <option value="1:1">1:1</option> | ||
| 2060 | <option value="9:16">9:16</option> | ||
| 2061 | <option value="16:9">16:9</option> | ||
| 2062 | <option value="3:4">3:4</option> | ||
| 2063 | <option value="4:3">4:3</option> | ||
| 2064 | <option value="3:2">3:2</option> | ||
| 2065 | <option value="2:3">2:3</option> | ||
| 2066 | <option value="5:4">5:4</option> | ||
| 2067 | <option value="4:5">4:5</option> | ||
| 2068 | <option value="21:9">21:9</option> | ||
| 2069 | </select> | ||
| 2070 | </div> | ||
| 2071 | </div> | ||
| 2041 | </div> | 2072 | </div> |
| 2042 | <div class="range-block" data-source="deepseek,aimlapi,openrouter,custom,claude,xai,makersuite,vertexai,pollinations,moonshot,mistralai,fireworks,cometapi,electronhub,azure_openai,nanogpt,zai"> | 2073 | <div class="range-block" data-source="deepseek,aimlapi,openrouter,custom,claude,xai,makersuite,vertexai,pollinations,moonshot,mistralai,fireworks,cometapi,electronhub,azure_openai,nanogpt,zai"> |
| 2043 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> | 2074 | <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand"> |
| @@ -355,6 +355,8 @@ export const settingsToUpdate = { | |||
| 355 | n: ['#n_openai', 'n', false, false], | 355 | n: ['#n_openai', 'n', false, false], |
| 356 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true, true], | 356 | bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true, true], |
| 357 | request_images: ['#openai_request_images', 'request_images', true, false], | 357 | request_images: ['#openai_request_images', 'request_images', true, false], |
| 358 | request_image_aspect_ratio: ['#request_image_aspect_ratio', 'request_image_aspect_ratio', false, false], | ||
| 359 | request_image_resolution: ['#request_image_resolution', 'request_image_resolution', false, false], | ||
| 358 | azure_base_url: ['#azure_base_url', 'azure_base_url', false, true], | 360 | azure_base_url: ['#azure_base_url', 'azure_base_url', false, true], |
| 359 | azure_deployment_name: ['#azure_deployment_name', 'azure_deployment_name', false, true], | 361 | azure_deployment_name: ['#azure_deployment_name', 'azure_deployment_name', false, true], |
| 360 | azure_api_version: ['#azure_api_version', 'azure_api_version', false, true], | 362 | azure_api_version: ['#azure_api_version', 'azure_api_version', false, true], |
| @@ -453,6 +455,8 @@ const default_settings = { | |||
| 453 | verbosity: verbosity_levels.auto, | 455 | verbosity: verbosity_levels.auto, |
| 454 | enable_web_search: false, | 456 | enable_web_search: false, |
| 455 | request_images: false, | 457 | request_images: false, |
| 458 | request_image_aspect_ratio: '', | ||
| 459 | request_image_resolution: '', | ||
| 456 | seed: -1, | 460 | seed: -1, |
| 457 | n: 1, | 461 | n: 1, |
| 458 | bind_preset_to_connection: true, | 462 | bind_preset_to_connection: true, |
| @@ -2330,6 +2334,8 @@ async function sendOpenAIRequest(type, messages, signal, { jsonSchema = null } = | |||
| 2330 | 'reasoning_effort': getReasoningEffort(), | 2334 | 'reasoning_effort': getReasoningEffort(), |
| 2331 | 'enable_web_search': Boolean(oai_settings.enable_web_search), | 2335 | 'enable_web_search': Boolean(oai_settings.enable_web_search), |
| 2332 | 'request_images': Boolean(oai_settings.request_images), | 2336 | 'request_images': Boolean(oai_settings.request_images), |
| 2337 | 'request_image_resolution': String(oai_settings.request_image_resolution), | ||
| 2338 | 'request_image_aspect_ratio': String(oai_settings.request_image_aspect_ratio), | ||
| 2333 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, | 2339 | 'custom_prompt_post_processing': oai_settings.custom_prompt_post_processing, |
| 2334 | 'verbosity': getVerbosity(), | 2340 | 'verbosity': getVerbosity(), |
| 2335 | }; | 2341 | }; |
| @@ -6331,6 +6337,16 @@ export function initOpenAI() { | |||
| 6331 | saveSettingsDebounced(); | 6337 | saveSettingsDebounced(); |
| 6332 | }); | 6338 | }); |
| 6333 | 6339 | ||
| 6340 | $('#request_image_resolution').on('input', function () { | ||
| 6341 | oai_settings.request_image_resolution = String($(this).val()); | ||
| 6342 | saveSettingsDebounced(); | ||
| 6343 | }); | ||
| 6344 | |||
| 6345 | $('#request_image_aspect_ratio').on('input', function () { | ||
| 6346 | oai_settings.request_image_aspect_ratio = String($(this).val()); | ||
| 6347 | saveSettingsDebounced(); | ||
| 6348 | }); | ||
| 6349 | |||
| 6334 | if (!CSS.supports('field-sizing', 'content')) { | 6350 | if (!CSS.supports('field-sizing', 'content')) { |
| 6335 | $(document).on('input', '#openai_settings .autoSetHeight', function () { | 6351 | $(document).on('input', '#openai_settings .autoSetHeight', function () { |
| 6336 | resetScrollHeight($(this)); | 6352 | resetScrollHeight($(this)); |
| @@ -367,6 +367,8 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 367 | const requestImages = Boolean(request.body.request_images); | 367 | const requestImages = Boolean(request.body.request_images); |
| 368 | const reasoningEffort = String(request.body.reasoning_effort); | 368 | const reasoningEffort = String(request.body.reasoning_effort); |
| 369 | const includeReasoning = Boolean(request.body.include_reasoning); | 369 | const includeReasoning = Boolean(request.body.include_reasoning); |
| 370 | const aspectRatio = String(request.body.request_image_aspect_ratio); | ||
| 371 | const imageSize = String(request.body.request_image_resolution); | ||
| 370 | const isGemma = model.includes('gemma'); | 372 | const isGemma = model.includes('gemma'); |
| 371 | const isLearnLM = model.includes('learnlm'); | 373 | const isLearnLM = model.includes('learnlm'); |
| 372 | 374 | ||
| @@ -397,6 +399,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 397 | ]; | 399 | ]; |
| 398 | 400 | ||
| 399 | const isThinkingConfigModel = m => (/^gemini-2.5-(flash|pro)/.test(m) && !/-image(-preview)?$/.test(m)) || (/^gemini-3-pro/.test(m)); | 401 | const isThinkingConfigModel = m => (/^gemini-2.5-(flash|pro)/.test(m) && !/-image(-preview)?$/.test(m)) || (/^gemini-3-pro/.test(m)); |
| 402 | const isImageSizeModel = m => /^gemini-3/.test(m); | ||
| 400 | 403 | ||
| 401 | const noSearchModels = [ | 404 | const noSearchModels = [ |
| 402 | 'gemini-2.0-flash-lite', | 405 | 'gemini-2.0-flash-lite', |
| @@ -411,8 +414,18 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 411 | } | 414 | } |
| 412 | 415 | ||
| 413 | const enableImageModality = requestImages && imageGenerationModels.includes(model); | 416 | const enableImageModality = requestImages && imageGenerationModels.includes(model); |
| 417 | const enableImageConfig = enableImageModality && (aspectRatio || imageSize); | ||
| 414 | if (enableImageModality) { | 418 | if (enableImageModality) { |
| 415 | generationConfig.responseModalities = ['text', 'image']; | 419 | generationConfig.responseModalities = ['text', 'image']; |
| 420 | if (enableImageConfig) { | ||
| 421 | generationConfig.imageConfig = {}; | ||
| 422 | if (imageSize && isImageSizeModel(model)) { | ||
| 423 | generationConfig.imageConfig.imageSize = imageSize; | ||
| 424 | } | ||
| 425 | if (aspectRatio) { | ||
| 426 | generationConfig.imageConfig.aspectRatio = aspectRatio; | ||
| 427 | } | ||
| 428 | } | ||
| 416 | } | 429 | } |
| 417 | 430 | ||
| 418 | const useSystemPrompt = !enableImageModality && !isGemma && request.body.use_sysprompt; | 431 | const useSystemPrompt = !enableImageModality && !isGemma && request.body.use_sysprompt; |