Gemini: add media resolution select (#4775)

This commit is contained in:
Cohee
2025-12-17 20:46:02 +02:00
committed by GitHub
parent 081c3e7b1c
commit 5accfbc5d8
3 changed files with 27 additions and 8 deletions
+1 -1
View File
@@ -2013,7 +2013,7 @@
<strong data-source="makersuite,vertexai" data-i18n="video_inlining_hint_4">Videos must be less than 20 MB and under 1 minute long.</strong>
<strong data-source="makersuite,vertexai" data-i18n="audio_inlining_hint_2">Audio must be less than 20 MB.</strong>
</div>
<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">
<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">
<div class="flex-container oneline-dropdown">
<label for="openai_inline_image_quality" data-i18n="Inline Image Quality">
Inline Image Quality
+2 -1
View File
@@ -3244,7 +3244,8 @@ class Message {
}
// Note: No compression for videos (unlike images)
this.content.push({ type: 'video_url', video_url: { 'url': video } });
const quality = oai_settings.inline_image_quality || default_settings.inline_image_quality;
this.content.push({ type: 'video_url', video_url: { 'url': video, 'detail': quality } });
try {
// Using Gemini calculation (263 tokens per second)
+24 -6
View File
@@ -25,6 +25,12 @@ export const PROMPT_PROCESSING_TYPE = {
SINGLE: 'single',
};
// 'auto' is intentionally unmapped
const GEMINI_MEDIA_RESOLUTION = {
low: 'media_resolution_low',
high: 'media_resolution_high',
};
/**
* @typedef {object} PromptNames
* @property {string} charName Character name
@@ -501,17 +507,27 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
//create the prompt parts
const parts = [];
message.content.forEach((part) => {
const addDataUrlPart = (/** @type {string} */ url, /** @type {string} */ defaultMimeType) => {
const addDataUrlPart = (/** @type {string} */ url, /** @type {string} */ defaultMimeType, /** @type {string?} */ detail = null) => {
if (url && url.startsWith('data:')) {
const [header, base64Data] = url.split(',');
const mimeType = header.match(/data:([^;]+)/)?.[1] || defaultMimeType;
const mediaResolution = GEMINI_MEDIA_RESOLUTION[detail] || null;
parts.push({
const part = {
inlineData: {
mimeType: mimeType,
data: base64Data,
},
});
};
// https://ai.google.dev/gemini-api/docs/gemini-3#media_resolution
if (/gemini-3/.test(model) && mediaResolution) {
part.mediaResolution = {
level: mediaResolution,
};
}
parts.push(part);
}
};
@@ -538,10 +554,12 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
});
} else if (part.type === 'image_url') {
const imageUrl = part.image_url?.url;
addDataUrlPart(imageUrl, 'image/png');
const detail = part.image_url?.detail;
addDataUrlPart(imageUrl, 'image/png', detail);
} else if (part.type === 'video_url') {
const videoUrl = part.video_url?.url;
addDataUrlPart(videoUrl, 'video/mp4');
const detail = part.video_url?.detail;
addDataUrlPart(videoUrl, 'video/mp4', detail);
} else if (part.type === 'audio_url') {
const audioUrl = part.audio_url?.url;
addDataUrlPart(audioUrl, 'audio/mpeg');
@@ -572,7 +590,7 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
contents[contents.length - 1].parts.push(part);
}
}
if (part.inlineData || part.functionCall || part.functionResponse || part.thoughtSignature) {
if (part.inlineData || part.functionCall || part.functionResponse || part.thoughtSignature || part.mediaResolution) {
contents[contents.length - 1].parts.push(part);
}
});