feat: add gemma 4 for AI studio (#5493)
* feat: add gemma 4 for AI studio * fix: update max context return value for gemma-3n-e4b-it model * refactor: iterate array of [regex, number] * gemma4: enable tool calling and sysprompt Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -3373,6 +3373,8 @@
|
||||
<option value="gemini-2.0-flash-lite">gemini-2.0-flash-lite</option>
|
||||
</optgroup>
|
||||
<optgroup label="Gemma">
|
||||
<option value="gemma-4-31b-it">gemma-4-31b-it</option>
|
||||
<option value="gemma-4-26b-a4b-it">gemma-4-26b-a4b-it</option>
|
||||
<option value="gemma-3n-e4b-it">gemma-3n-e4b-it</option>
|
||||
<option value="gemma-3n-e2b-it">gemma-3n-e2b-it</option>
|
||||
<option value="gemma-3-27b-it">gemma-3-27b-it</option>
|
||||
|
||||
@@ -153,6 +153,11 @@
|
||||
<option data-type="google" value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option>
|
||||
<option data-type="google" value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option>
|
||||
<option data-type="google" value="gemini-robotics-er-1.5-preview">gemini-robotics-er-1.5-preview</option>
|
||||
<option data-type="google" value="gemma-4-31b-it">gemma-4-31b-it</option>
|
||||
<option data-type="google" value="gemma-4-26b-a4b-it">gemma-4-26b-a4b-it</option>
|
||||
<option data-type="google" value="gemma-3-27b-it">gemma-3-27b-it</option>
|
||||
<option data-type="google" value="gemma-3-12b-it">gemma-3-12b-it</option>
|
||||
<option data-type="google" value="gemma-3-4b-it">gemma-3-4b-it</option>
|
||||
<option data-type="vertexai" value="gemini-3.1-pro-preview">gemini-3.1-pro-preview</option>
|
||||
<option data-type="vertexai" value="gemini-3.1-flash-lite-preview">gemini-3.1-flash-lite-preview</option>
|
||||
<option data-type="vertexai" value="gemini-3.1-flash-image-preview">gemini-3.1-flash-image-preview</option>
|
||||
|
||||
+69
-22
@@ -4933,6 +4933,65 @@ function getMaxContextOpenAI(value) {
|
||||
return max_128k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum context size for Gemini models based on model identifier and optional model list.
|
||||
* @param {string} model Model identifier
|
||||
* @param {boolean} isUnlocked Whether context limits are unlocked
|
||||
* @returns {number} Maximum context size in tokens
|
||||
*/
|
||||
function getGeminiMaxContext(model, isUnlocked) {
|
||||
if (isUnlocked) {
|
||||
return unlocked_max;
|
||||
}
|
||||
|
||||
if (Array.isArray(model_list) && model_list.length > 0) {
|
||||
const contextLength = model_list.find((record) => record.id === model)?.inputTokenLimit;
|
||||
if (Number.isFinite(contextLength) && contextLength > 0) {
|
||||
return contextLength;
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {[RegExp, number][]} */
|
||||
const contextMap = [
|
||||
[/gemini-2\.5-flash-image/, max_32k],
|
||||
[/gemini-3-pro-image/, max_64k],
|
||||
[/gemini-(?:3[.\d]*|2\.(?:5|0))-(pro|flash)/, max_1mil],
|
||||
[/(gemini-exp|learnlm-2\.0-flash|gemini-robotics)/, max_1mil],
|
||||
[/gemma-3-27b-it/, max_128k],
|
||||
[/gemma-3n-e4b-it/, max_8k],
|
||||
[/gemma-3/, max_32k],
|
||||
[/gemma-4/, max_256k],
|
||||
];
|
||||
|
||||
for (const [regex, max] of contextMap) {
|
||||
if (regex.test(model)) {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
return max_128k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum temperature for Gemini models based on model identifier and optional model list.
|
||||
* @param {string} model Model identifier
|
||||
* @returns {number} Maximum temperature for Gemini models
|
||||
*/
|
||||
function getGeminiMaxTemp(model) {
|
||||
if (Array.isArray(model_list) && model_list.length > 0) {
|
||||
const temp = model_list.find((record) => record.id === model)?.temperature;
|
||||
if (Number.isFinite(temp) && temp > 0) {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (/(vision|ultra|gemma)/.test(model)) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return 2.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum context size for the Mistral model
|
||||
* @param {string} model Model identifier
|
||||
@@ -5443,28 +5502,11 @@ async function onModelChange() {
|
||||
}
|
||||
|
||||
if ([chat_completion_sources.MAKERSUITE, chat_completion_sources.VERTEXAI].includes(oai_settings.chat_completion_source)) {
|
||||
if (oai_settings.max_context_unlocked) {
|
||||
$('#openai_max_context').attr('max', max_2mil);
|
||||
} else if (value.includes('gemini-2.5-flash-image')) {
|
||||
$('#openai_max_context').attr('max', max_32k);
|
||||
} else if (value.includes('gemini-3-pro-image')) {
|
||||
$('#openai_max_context').attr('max', max_64k);
|
||||
} else if (/gemini-3[.\d]*-(pro|flash)/.test(value) || /gemini-2.5-(pro|flash)/.test(value) || /gemini-2.0-(pro|flash)/.test(value)) {
|
||||
$('#openai_max_context').attr('max', max_1mil);
|
||||
} else if (value.includes('gemini-exp') || value.includes('learnlm-2.0-flash') || value.includes('gemini-robotics')) {
|
||||
$('#openai_max_context').attr('max', max_1mil);
|
||||
} else if (value.includes('gemma-3-27b-it')) {
|
||||
$('#openai_max_context').attr('max', max_128k);
|
||||
} else if (value.includes('gemma-3n-e4b-it')) {
|
||||
$('#openai_max_context').attr('max', max_8k);
|
||||
} else if (value.includes('gemma-3')) {
|
||||
$('#openai_max_context').attr('max', max_32k);
|
||||
} else {
|
||||
$('#openai_max_context').attr('max', max_32k);
|
||||
}
|
||||
let makersuite_max_temp = (value.includes('vision') || value.includes('ultra') || value.includes('gemma')) ? 1.0 : 2.0;
|
||||
oai_settings.temp_openai = Math.min(makersuite_max_temp, oai_settings.temp_openai);
|
||||
$('#temp_openai').attr('max', makersuite_max_temp).val(oai_settings.temp_openai).trigger('input');
|
||||
const contextSize = getGeminiMaxContext(value, oai_settings.max_context_unlocked);
|
||||
const maxTemp = getGeminiMaxTemp(value);
|
||||
$('#openai_max_context').attr('max', contextSize);
|
||||
oai_settings.temp_openai = Math.min(maxTemp, oai_settings.temp_openai);
|
||||
$('#temp_openai').attr('max', maxTemp).val(oai_settings.temp_openai).trigger('input');
|
||||
oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context);
|
||||
$('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
|
||||
}
|
||||
@@ -6040,6 +6082,10 @@ export function isImageInliningSupported() {
|
||||
'gemini-exp-1206',
|
||||
'learnlm',
|
||||
'gemini-robotics',
|
||||
'gemma-3-27b',
|
||||
'gemma-3-12b',
|
||||
'gemma-3-4b',
|
||||
'gemma-4',
|
||||
// MistralAI
|
||||
'mistral-small-2503',
|
||||
'mistral-small-2506',
|
||||
@@ -6144,6 +6190,7 @@ export function isVideoInliningSupported() {
|
||||
'gemini-2.5',
|
||||
'gemini-exp-1206',
|
||||
'gemini-3',
|
||||
'gemma-4',
|
||||
// Z.AI (GLM)
|
||||
'glm-4.5v',
|
||||
'glm-4.6v',
|
||||
|
||||
@@ -459,7 +459,7 @@ async function sendMakerSuiteRequest(request, response) {
|
||||
const includeReasoning = Boolean(request.body.include_reasoning);
|
||||
const aspectRatio = String(request.body.request_image_aspect_ratio);
|
||||
const imageSize = String(request.body.request_image_resolution);
|
||||
const isGemma = model.includes('gemma');
|
||||
const isGemma3 = /gemma-3/.test(model);
|
||||
const isLearnLM = model.includes('learnlm');
|
||||
|
||||
const responseMimeType = request.body.responseMimeType ?? (request.body.json_schema ? 'application/json' : undefined);
|
||||
@@ -519,13 +519,13 @@ async function sendMakerSuiteRequest(request, response) {
|
||||
}
|
||||
}
|
||||
|
||||
const useSystemPrompt = !enableImageModality && !isGemma && request.body.use_sysprompt;
|
||||
const useSystemPrompt = !enableImageModality && !isGemma3 && request.body.use_sysprompt;
|
||||
|
||||
const tools = [];
|
||||
const prompt = convertGooglePrompt(request.body.messages, model, useSystemPrompt, getPromptNames(request));
|
||||
const safetySettings = [...GEMINI_SAFETY, ...(useVertexAi ? VERTEX_SAFETY : [])];
|
||||
|
||||
if (Array.isArray(request.body.tools) && request.body.tools.length > 0 && !enableImageModality && !isGemma) {
|
||||
if (Array.isArray(request.body.tools) && request.body.tools.length > 0 && !enableImageModality && !isGemma3) {
|
||||
const functionDeclarations = [];
|
||||
const customTools = [];
|
||||
for (const tool of request.body.tools) {
|
||||
@@ -550,7 +550,7 @@ async function sendMakerSuiteRequest(request, response) {
|
||||
}
|
||||
}
|
||||
|
||||
if (enableWebSearch && !enableImageModality && !isGemma && !isLearnLM && !noSearchModels.includes(model)) {
|
||||
if (enableWebSearch && !enableImageModality && !isGemma3 && !isLearnLM && !noSearchModels.includes(model)) {
|
||||
// Tool use with function calling is unsupported
|
||||
if (!tools.some(t => t.function_declarations)) {
|
||||
tools.push({ google_search: {} });
|
||||
@@ -1832,6 +1832,7 @@ router.post('/status', async function (request, statusResponse) {
|
||||
const models = data.models
|
||||
?.filter(model => model.supportedGenerationMethods?.includes('generateContent'))
|
||||
?.map(model => ({
|
||||
...model,
|
||||
id: model.name.replace('models/', ''),
|
||||
})) || [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user