From 48d8762ccfc1b9a6144b358ecedfbcab71a4692d Mon Sep 17 00:00:00 2001 From: Neal Shah <30693865+ProgrammerIn-wonderland@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:36:00 +0400 Subject: [PATCH] Gemini nano banana pro updated (#2012) * Update AI.js * Update GeminiImageGenerationService.js * Update cost map * Gemini to OpenAI SDK refactor (#2014) * WIP Gemini OpenAI refactor * refactor: gemini open ai service + geminiCostMap * Gemini Service fixes * Cleaning up old Gemini cruft --------- Co-authored-by: Daniel Salazar --------- Co-authored-by: Nihhaar0002 Co-authored-by: Daniel Salazar --- .../puterai/GeminiImageGenerationService.js | 16 ++++++++++++---- .../MeteringService/costMaps/geminiCostMap.ts | 1 + src/puter-js/src/modules/AI.js | 6 +++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/backend/src/modules/puterai/GeminiImageGenerationService.js b/src/backend/src/modules/puterai/GeminiImageGenerationService.js index c30ce8afd..4d1b33711 100644 --- a/src/backend/src/modules/puterai/GeminiImageGenerationService.js +++ b/src/backend/src/modules/puterai/GeminiImageGenerationService.js @@ -42,6 +42,9 @@ class GeminiImageGenerationService extends BaseService { 'gemini-2.5-flash-image-preview': { '1024x1024': 0.039, }, + 'gemini-3-pro-image-preview': { + '1024x1024': 0.156, + }, }; } @@ -192,9 +195,10 @@ class GeminiImageGenerationService extends BaseService { } const response = await this.genAI.models.generateContent({ - model: 'gemini-2.5-flash-image-preview', - contents: contents, + model, + contents, }); + // Metering usage tracking // Gemini usage: always 1 image, resolution, cost, model this.meteringService.incrementUsage(actor, usageType, 1); @@ -221,10 +225,14 @@ class GeminiImageGenerationService extends BaseService { * @returns {Array} Array of valid ratio objects * @private */ - _getValidRatios (model) { - if ( model === 'gemini-2.5-flash-image-preview' ) { + _getValidRatios(model) { + if ( + model === 'gemini-2.5-flash-image-preview' || + model === 'gemini-3-pro-image-preview' + ) { return [this.constructor.RATIO_SQUARE]; } + return []; } _validate_ratio (ratio, model) { diff --git a/src/backend/src/services/MeteringService/costMaps/geminiCostMap.ts b/src/backend/src/services/MeteringService/costMaps/geminiCostMap.ts index 4c45e8a41..81c6f7e01 100644 --- a/src/backend/src/services/MeteringService/costMaps/geminiCostMap.ts +++ b/src/backend/src/services/MeteringService/costMaps/geminiCostMap.ts @@ -24,4 +24,5 @@ export const GEMINI_COST_MAP = { 'gemini:gemini-3-pro-preview:promptTokenCount': 25, 'gemini:gemini-3-pro-preview:candidatesTokenCount': 100, 'gemini:gemini-2.5-flash-image-preview:1024x1024': 3_900_000, + 'gemini:gemini-3-pro-image-preview:1024x1024': 15_600_000 }; diff --git a/src/puter-js/src/modules/AI.js b/src/puter-js/src/modules/AI.js index d8f5e850b..f9eb618bf 100644 --- a/src/puter-js/src/modules/AI.js +++ b/src/puter-js/src/modules/AI.js @@ -1001,6 +1001,10 @@ class AI { options.model = 'gemini-2.5-flash-image-preview'; } + if (options.model === "nano-banana-pro") { + options.model = "gemini-3-pro-image-preview"; + } + const driverHint = typeof options.driver === 'string' ? options.driver : undefined; const providerRaw = typeof options.provider === 'string' ? options.provider @@ -1019,7 +1023,7 @@ class AI { AIService = 'gemini-image-generation'; } else if ( providerHint === 'together' || providerHint === 'together-ai' ) { AIService = 'together-image-generation'; - } else if ( options.model === 'gemini-2.5-flash-image-preview' ) { + } else if (options.model === 'gemini-2.5-flash-image-preview' || options.model === "gemini-3-pro-image-preview" ) { AIService = 'gemini-image-generation'; } else if ( looksLikeTogetherModel ) { AIService = 'together-image-generation';