| @@ -2013,7 +2013,7 @@ | |||
| 2013 | <strong data-source="makersuite,vertexai" data-i18n="video_inlining_hint_4">Videos must be less than 20 MB and under 1 minute long.</strong> | 2013 | <strong data-source="makersuite,vertexai" data-i18n="video_inlining_hint_4">Videos must be less than 20 MB and under 1 minute long.</strong> |
| 2014 | <strong data-source="makersuite,vertexai" data-i18n="audio_inlining_hint_2">Audio must be less than 20 MB.</strong> | 2014 | <strong data-source="makersuite,vertexai" data-i18n="audio_inlining_hint_2">Audio must be less than 20 MB.</strong> |
| 2015 | </div> | 2015 | </div> |
| 2016 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai,pollinations,cohere,cometapi,nanogpt,moonshot,aimlapi,openrouter,mistralai,electronhub,azure_openai,zai,siliconflow,chutes"> | 2016 | <div class="flex-container flexFlowColumn wide100p textAlignCenter marginTop10" data-source="openai,custom,xai,pollinations,cohere,cometapi,nanogpt,moonshot,aimlapi,openrouter,mistralai,electronhub,azure_openai,zai,siliconflow,chutes,makersuite,vertexai"> |
| 2017 | <div class="flex-container oneline-dropdown"> | 2017 | <div class="flex-container oneline-dropdown"> |
| 2018 | <label for="openai_inline_image_quality" data-i18n="Inline Image Quality"> | 2018 | <label for="openai_inline_image_quality" data-i18n="Inline Image Quality"> |
| 2019 | Inline Image Quality | 2019 | Inline Image Quality |
| @@ -3244,7 +3244,8 @@ class Message { | |||
| 3244 | } | 3244 | } |
| 3245 | 3245 | ||
| 3246 | // Note: No compression for videos (unlike images) | 3246 | // Note: No compression for videos (unlike images) |
| 3247 | this.content.push({ type: 'video_url', video_url: { 'url': video } }); | 3247 | const quality = oai_settings.inline_image_quality || default_settings.inline_image_quality; |
| 3248 | this.content.push({ type: 'video_url', video_url: { 'url': video, 'detail': quality } }); | ||
| 3248 | 3249 | ||
| 3249 | try { | 3250 | try { |
| 3250 | // Using Gemini calculation (263 tokens per second) | 3251 | // Using Gemini calculation (263 tokens per second) |
| @@ -25,6 +25,12 @@ export const PROMPT_PROCESSING_TYPE = { | |||
| 25 | SINGLE: 'single', | 25 | SINGLE: 'single', |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | // 'auto' is intentionally unmapped | ||
| 29 | const GEMINI_MEDIA_RESOLUTION = { | ||
| 30 | low: 'media_resolution_low', | ||
| 31 | high: 'media_resolution_high', | ||
| 32 | }; | ||
| 33 | |||
| 28 | /** | 34 | /** |
| 29 | * @typedef {object} PromptNames | 35 | * @typedef {object} PromptNames |
| 30 | * @property {string} charName Character name | 36 | * @property {string} charName Character name |
| @@ -501,17 +507,27 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) { | |||
| 501 | //create the prompt parts | 507 | //create the prompt parts |
| 502 | const parts = []; | 508 | const parts = []; |
| 503 | message.content.forEach((part) => { | 509 | message.content.forEach((part) => { |
| 504 | const addDataUrlPart = (/** @type {string} */ url, /** @type {string} */ defaultMimeType) => { | 510 | const addDataUrlPart = (/** @type {string} */ url, /** @type {string} */ defaultMimeType, /** @type {string?} */ detail = null) => { |
| 505 | if (url && url.startsWith('data:')) { | 511 | if (url && url.startsWith('data:')) { |
| 506 | const [header, base64Data] = url.split(','); | 512 | const [header, base64Data] = url.split(','); |
| 507 | const mimeType = header.match(/data:([^;]+)/)?.[1] || defaultMimeType; | 513 | const mimeType = header.match(/data:([^;]+)/)?.[1] || defaultMimeType; |
| 514 | const mediaResolution = GEMINI_MEDIA_RESOLUTION[detail] || null; | ||
| 508 | 515 | ||
| 509 | parts.push({ | 516 | const part = { |
| 510 | inlineData: { | 517 | inlineData: { |
| 511 | mimeType: mimeType, | 518 | mimeType: mimeType, |
| 512 | data: base64Data, | 519 | data: base64Data, |
| 513 | }, | 520 | }, |
| 514 | }); | 521 | }; |
| 522 | |||
| 523 | // https://ai.google.dev/gemini-api/docs/gemini-3#media_resolution | ||
| 524 | if (/gemini-3/.test(model) && mediaResolution) { | ||
| 525 | part.mediaResolution = { | ||
| 526 | level: mediaResolution, | ||
| 527 | }; | ||
| 528 | } | ||
| 529 | |||
| 530 | parts.push(part); | ||
| 515 | } | 531 | } |
| 516 | }; | 532 | }; |
| 517 | 533 | ||
| @@ -538,10 +554,12 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) { | |||
| 538 | }); | 554 | }); |
| 539 | } else if (part.type === 'image_url') { | 555 | } else if (part.type === 'image_url') { |
| 540 | const imageUrl = part.image_url?.url; | 556 | const imageUrl = part.image_url?.url; |
| 541 | addDataUrlPart(imageUrl, 'image/png'); | 557 | const detail = part.image_url?.detail; |
| 558 | addDataUrlPart(imageUrl, 'image/png', detail); | ||
| 542 | } else if (part.type === 'video_url') { | 559 | } else if (part.type === 'video_url') { |
| 543 | const videoUrl = part.video_url?.url; | 560 | const videoUrl = part.video_url?.url; |
| 544 | addDataUrlPart(videoUrl, 'video/mp4'); | 561 | const detail = part.video_url?.detail; |
| 562 | addDataUrlPart(videoUrl, 'video/mp4', detail); | ||
| 545 | } else if (part.type === 'audio_url') { | 563 | } else if (part.type === 'audio_url') { |
| 546 | const audioUrl = part.audio_url?.url; | 564 | const audioUrl = part.audio_url?.url; |
| 547 | addDataUrlPart(audioUrl, 'audio/mpeg'); | 565 | addDataUrlPart(audioUrl, 'audio/mpeg'); |
| @@ -572,7 +590,7 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) { | |||
| 572 | contents[contents.length - 1].parts.push(part); | 590 | contents[contents.length - 1].parts.push(part); |
| 573 | } | 591 | } |
| 574 | } | 592 | } |
| 575 | if (part.inlineData || part.functionCall || part.functionResponse || part.thoughtSignature) { | 593 | if (part.inlineData || part.functionCall || part.functionResponse || part.thoughtSignature || part.mediaResolution) { |
| 576 | contents[contents.length - 1].parts.push(part); | 594 | contents[contents.length - 1].parts.push(part); |
| 577 | } | 595 | } |
| 578 | }); | 596 | }); |