feat(Google Gemini Node): Show Nano Banana 2.1 and 2 Lite in the image model list (#40596)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alexander Gekov 2026-10-08 09:59:08 +00:00 committed by GitHub
parent c133d6c893
commit 97c54f618c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 3 deletions

View File

@ -49,6 +49,12 @@ const mockResponse = {
{
name: 'models/gemini-3.1-flash-image-preview',
},
{
name: 'models/gemini-nano-banana-2.1',
},
{
name: 'models/gemini-3.1-flash-lite-image',
},
],
};
@ -153,6 +159,16 @@ describe('GoogleGemini -> listSearch', () => {
name: 'models/gemini-3.1-flash-image-preview (Nano Banana 2)',
value: 'models/gemini-3.1-flash-image-preview',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'models/gemini-nano-banana-2.1 (Nano Banana 2.1)',
value: 'models/gemini-nano-banana-2.1',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'models/gemini-3.1-flash-lite-image (Nano Banana 2 Lite)',
value: 'models/gemini-3.1-flash-lite-image',
},
],
});
});
@ -196,6 +212,16 @@ describe('GoogleGemini -> listSearch', () => {
name: 'models/gemini-3.1-flash-image-preview (Nano Banana 2)',
value: 'models/gemini-3.1-flash-image-preview',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'models/gemini-nano-banana-2.1 (Nano Banana 2.1)',
value: 'models/gemini-nano-banana-2.1',
},
{
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
name: 'models/gemini-3.1-flash-lite-image (Nano Banana 2 Lite)',
value: 'models/gemini-3.1-flash-lite-image',
},
],
});
});

View File

@ -2,6 +2,11 @@ import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow'
import { apiRequest } from '../transport';
/** Nano Banana ids do not contain the word "image". */
function isImageModel(model: string): boolean {
return model.includes('image') || model.includes('nano-banana');
}
async function baseModelSearch(
this: ILoadOptionsFunctions,
modelFilter: (model: string) => boolean,
@ -32,9 +37,9 @@ export async function modelSearch(
return await baseModelSearch.call(
this,
(model) =>
!isImageModel(model) &&
!model.includes('embedding') &&
!model.includes('aqa') &&
!model.includes('image') &&
!model.includes('vision') &&
!model.includes('veo') &&
!model.includes('audio') &&
@ -50,9 +55,9 @@ export async function audioModelSearch(
return await baseModelSearch.call(
this,
(model) =>
!isImageModel(model) &&
!model.includes('embedding') &&
!model.includes('aqa') &&
!model.includes('image') &&
!model.includes('vision') &&
!model.includes('veo') &&
!model.includes('tts'), // we don't have a tts operation
@ -64,8 +69,17 @@ export async function imageGenerationModelSearch(
this: ILoadOptionsFunctions,
filter?: string,
): Promise<INodeListSearchResult> {
const rawResult = await baseModelSearch.call(this, (model) => model.includes('image'));
const rawResult = await baseModelSearch.call(this, isImageModel);
let results = rawResult.results.map((r) => {
if (r.name.includes('gemini-nano-banana-2.1')) {
return { name: `${r.name} (Nano Banana 2.1)`, value: r.value };
}
// The Lite id also contains "gemini-3.1-flash-image". Match it first.
if (r.name.includes('gemini-3.1-flash-lite-image')) {
return { name: `${r.name} (Nano Banana 2 Lite)`, value: r.value };
}
if (r.name.includes('gemini-3.1-flash-image')) {
return { name: `${r.name} (Nano Banana 2)`, value: r.value };
}