2026-01-03 11:26:46 -05:00
const path = require ( 'path' ) ;
const sharp = require ( 'sharp' ) ;
const { v4 } = require ( 'uuid' ) ;
2026-01-12 09:51:48 -05:00
const { ProxyAgent } = require ( 'undici' ) ;
2026-01-03 11:26:46 -05:00
const { GoogleGenAI } = require ( '@google/genai' ) ;
const { tool } = require ( '@langchain/core/tools' ) ;
const { logger } = require ( '@librechat/data-schemas' ) ;
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
const { ContentTypes , EImageOutputType } = require ( 'librechat-data-provider' ) ;
2026-01-03 11:26:46 -05:00
const {
geminiToolkit ,
loadServiceKey ,
getBalanceConfig ,
getTransactionsConfig ,
} = require ( '@librechat/api' ) ;
const { getStrategyFunctions } = require ( '~/server/services/Files/strategies' ) ;
const { spendTokens } = require ( '~/models/spendTokens' ) ;
const { getFiles } = require ( '~/models/File' ) ;
2026-01-12 09:51:48 -05:00
/ * *
* Configure proxy support for Google APIs
* This wraps globalThis . fetch to add a proxy dispatcher only for googleapis . com URLs
* This is necessary because @ google / genai SDK doesn ' t support custom fetch or httpOptions . dispatcher
* /
if ( process . env . PROXY ) {
const originalFetch = globalThis . fetch ;
const proxyAgent = new ProxyAgent ( process . env . PROXY ) ;
globalThis . fetch = function ( url , options = { } ) {
const urlString = url . toString ( ) ;
if ( urlString . includes ( 'googleapis.com' ) ) {
options = { ... options , dispatcher : proxyAgent } ;
}
return originalFetch . call ( this , url , options ) ;
} ;
}
2026-01-03 11:26:46 -05:00
/ * *
* Get the default service key file path ( consistent with main Google endpoint )
* @ returns { string } - The default path to the service key file
* /
function getDefaultServiceKeyPath ( ) {
return (
process . env . GOOGLE _SERVICE _KEY _FILE || path . join ( process . cwd ( ) , 'api' , 'data' , 'auth.json' )
) ;
}
const displayMessage =
"Gemini displayed an image. All generated images are already plainly visible, so don't repeat the descriptions in detail. Do not list download links as they are available in the UI already. The user may download the images by clicking on them, but do not mention anything about downloading to the user." ;
/ * *
* Replaces unwanted characters from the input string
* @ param { string } inputString - The input string to process
* @ returns { string } - The processed string
* /
function replaceUnwantedChars ( inputString ) {
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
return (
inputString
? . replace ( /\r\n|\r|\n/g , ' ' )
. replace ( /"/g , '' )
. trim ( ) || ''
) ;
2026-01-03 11:26:46 -05:00
}
/ * *
* Convert image buffer to target format if needed
* @ param { Buffer } inputBuffer - The input image buffer
* @ param { string } targetFormat - The target format ( png , jpeg , webp )
* @ returns { Promise < { buffer : Buffer , format : string } > } - Converted buffer and format
* /
async function convertImageFormat ( inputBuffer , targetFormat ) {
const metadata = await sharp ( inputBuffer ) . metadata ( ) ;
const currentFormat = metadata . format ;
// Normalize format names (jpg -> jpeg)
const normalizedTarget = targetFormat === 'jpg' ? 'jpeg' : targetFormat . toLowerCase ( ) ;
const normalizedCurrent = currentFormat === 'jpg' ? 'jpeg' : currentFormat ;
// If already in target format, return as-is
if ( normalizedCurrent === normalizedTarget ) {
return { buffer : inputBuffer , format : normalizedTarget } ;
}
// Convert to target format
const convertedBuffer = await sharp ( inputBuffer ) . toFormat ( normalizedTarget ) . toBuffer ( ) ;
return { buffer : convertedBuffer , format : normalizedTarget } ;
}
/ * *
* Initialize Gemini client ( supports both Gemini API and Vertex AI )
* Priority : API key ( from options , resolved by loadAuthValues ) > Vertex AI service account
* @ param { Object } options - Initialization options
* @ param { string } [ options . GEMINI _API _KEY ] - Gemini API key ( resolved by loadAuthValues )
* @ param { string } [ options . GOOGLE _KEY ] - Google API key ( resolved by loadAuthValues )
* @ returns { Promise < GoogleGenAI > } - The initialized client
* /
async function initializeGeminiClient ( options = { } ) {
const geminiKey = options . GEMINI _API _KEY ;
if ( geminiKey ) {
logger . debug ( '[GeminiImageGen] Using Gemini API with GEMINI_API_KEY' ) ;
return new GoogleGenAI ( { apiKey : geminiKey } ) ;
}
const googleKey = options . GOOGLE _KEY ;
if ( googleKey ) {
logger . debug ( '[GeminiImageGen] Using Gemini API with GOOGLE_KEY' ) ;
return new GoogleGenAI ( { apiKey : googleKey } ) ;
}
logger . debug ( '[GeminiImageGen] Using Vertex AI with service account' ) ;
const credentialsPath = getDefaultServiceKeyPath ( ) ;
const serviceKey = await loadServiceKey ( credentialsPath ) ;
if ( ! serviceKey || ! serviceKey . project _id ) {
throw new Error (
'Gemini Image Generation requires one of: user-provided API key, GEMINI_API_KEY or GOOGLE_KEY env var, or a valid Google service account. ' +
` Service account file not found or invalid at: ${ credentialsPath } ` ,
) ;
}
return new GoogleGenAI ( {
vertexai : true ,
project : serviceKey . project _id ,
location : process . env . GOOGLE _LOC || process . env . GOOGLE _CLOUD _LOCATION || 'global' ,
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
googleAuthOptions : { credentials : serviceKey } ,
2026-01-03 11:26:46 -05:00
} ) ;
}
/ * *
* Convert image files to Gemini inline data format
* @ param { Object } params - Parameters
* @ returns { Promise < Array > } - Array of inline data objects
* /
async function convertImagesToInlineData ( { imageFiles , image _ids , req , fileStrategy } ) {
if ( ! image _ids || image _ids . length === 0 ) {
return [ ] ;
}
const streamMethods = { } ;
const requestFilesMap = Object . fromEntries ( imageFiles . map ( ( f ) => [ f . file _id , { ... f } ] ) ) ;
const orderedFiles = new Array ( image _ids . length ) ;
const idsToFetch = [ ] ;
const indexOfMissing = Object . create ( null ) ;
for ( let i = 0 ; i < image _ids . length ; i ++ ) {
const id = image _ids [ i ] ;
const file = requestFilesMap [ id ] ;
if ( file ) {
orderedFiles [ i ] = file ;
} else {
idsToFetch . push ( id ) ;
indexOfMissing [ id ] = i ;
}
}
if ( idsToFetch . length && req ? . user ? . id ) {
const fetchedFiles = await getFiles (
{
user : req . user . id ,
file _id : { $in : idsToFetch } ,
height : { $exists : true } ,
width : { $exists : true } ,
} ,
{ } ,
{ } ,
) ;
for ( const file of fetchedFiles ) {
requestFilesMap [ file . file _id ] = file ;
orderedFiles [ indexOfMissing [ file . file _id ] ] = file ;
}
}
const inlineDataArray = [ ] ;
for ( const imageFile of orderedFiles ) {
if ( ! imageFile ) continue ;
try {
const source = imageFile . source || fileStrategy ;
if ( ! source ) continue ;
let getDownloadStream = streamMethods [ source ] ;
if ( ! getDownloadStream ) {
( { getDownloadStream } = getStrategyFunctions ( source ) ) ;
streamMethods [ source ] = getDownloadStream ;
}
if ( ! getDownloadStream ) continue ;
const stream = await getDownloadStream ( req , imageFile . filepath ) ;
if ( ! stream ) continue ;
const chunks = [ ] ;
for await ( const chunk of stream ) {
chunks . push ( chunk ) ;
}
const buffer = Buffer . concat ( chunks ) ;
const base64Data = buffer . toString ( 'base64' ) ;
const mimeType = imageFile . type || 'image/png' ;
inlineDataArray . push ( {
inlineData : { mimeType , data : base64Data } ,
} ) ;
} catch ( error ) {
logger . error ( '[GeminiImageGen] Error processing image:' , imageFile . file _id , error ) ;
}
}
return inlineDataArray ;
}
/ * *
* Check for safety blocks in API response
* @ param { Object } response - The API response
* @ returns { Object | null } - Safety block info or null
* /
function checkForSafetyBlock ( response ) {
if ( ! response ? . candidates ? . length ) {
return { reason : 'NO_CANDIDATES' , message : 'No candidates returned' } ;
}
const candidate = response . candidates [ 0 ] ;
const finishReason = candidate . finishReason ;
if ( finishReason === 'SAFETY' || finishReason === 'PROHIBITED_CONTENT' ) {
return { reason : finishReason , message : 'Content blocked by safety filters' } ;
}
if ( finishReason === 'RECITATION' ) {
return { reason : finishReason , message : 'Content blocked due to recitation concerns' } ;
}
if ( candidate . safetyRatings ) {
for ( const rating of candidate . safetyRatings ) {
if ( rating . probability === 'HIGH' || rating . blocked === true ) {
return {
reason : 'SAFETY_RATING' ,
message : ` Blocked due to ${ rating . category } ` ,
category : rating . category ,
} ;
}
}
}
return null ;
}
/ * *
* Record token usage for balance tracking
* @ param { Object } params - Parameters
* @ param { Object } params . usageMetadata - The usage metadata from API response
* @ param { Object } params . req - The request object
* @ param { string } params . userId - The user ID
* @ param { string } params . conversationId - The conversation ID
* @ param { string } params . model - The model name
* /
async function recordTokenUsage ( { usageMetadata , req , userId , conversationId , model } ) {
if ( ! usageMetadata ) {
logger . debug ( '[GeminiImageGen] No usage metadata available for balance tracking' ) ;
return ;
}
const appConfig = req ? . config ;
const balance = getBalanceConfig ( appConfig ) ;
const transactions = getTransactionsConfig ( appConfig ) ;
// Skip if neither balance nor transactions are enabled
if ( ! balance ? . enabled && transactions ? . enabled === false ) {
return ;
}
const promptTokens = usageMetadata . prompt _token _count || usageMetadata . promptTokenCount || 0 ;
const completionTokens =
usageMetadata . candidates _token _count || usageMetadata . candidatesTokenCount || 0 ;
if ( promptTokens === 0 && completionTokens === 0 ) {
logger . debug ( '[GeminiImageGen] No tokens to record' ) ;
return ;
}
logger . debug ( '[GeminiImageGen] Recording token usage:' , {
promptTokens ,
completionTokens ,
model ,
conversationId ,
} ) ;
try {
await spendTokens (
{
user : userId ,
model ,
conversationId ,
context : 'image_generation' ,
balance ,
transactions ,
} ,
{
promptTokens ,
completionTokens ,
} ,
) ;
} catch ( error ) {
logger . error ( '[GeminiImageGen] Error recording token usage:' , error ) ;
}
}
/ * *
* Creates Gemini Image Generation tool
* @ param { Object } fields - Configuration fields
* @ returns { ReturnType < tool > } - The image generation tool
* /
function createGeminiImageTool ( fields = { } ) {
const override = fields . override ? ? false ;
if ( ! override && ! fields . isAgent ) {
throw new Error ( 'This tool is only available for agents.' ) ;
}
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
const { req , imageFiles = [ ] , userId , fileStrategy , GEMINI _API _KEY , GOOGLE _KEY } = fields ;
2026-01-03 11:26:46 -05:00
const imageOutputType = fields . imageOutputType || EImageOutputType . PNG ;
const geminiImageGenTool = tool (
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
async ( { prompt , image _ids , aspectRatio , imageSize } , runnableConfig ) => {
2026-01-03 11:26:46 -05:00
if ( ! prompt ) {
throw new Error ( 'Missing required field: prompt' ) ;
}
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
logger . debug ( '[GeminiImageGen] Generating image' , { aspectRatio , imageSize } ) ;
2026-01-03 11:26:46 -05:00
let ai ;
try {
ai = await initializeGeminiClient ( {
GEMINI _API _KEY ,
GOOGLE _KEY ,
} ) ;
} catch ( error ) {
logger . error ( '[GeminiImageGen] Failed to initialize client:' , error ) ;
return [
[ { type : ContentTypes . TEXT , text : ` Failed to initialize Gemini: ${ error . message } ` } ] ,
{ content : [ ] , file _ids : [ ] } ,
] ;
}
const contents = [ { text : replaceUnwantedChars ( prompt ) } ] ;
if ( image _ids ? . length > 0 ) {
const contextImages = await convertImagesToInlineData ( {
imageFiles ,
image _ids ,
req ,
fileStrategy ,
} ) ;
contents . push ( ... contextImages ) ;
logger . debug ( '[GeminiImageGen] Added' , contextImages . length , 'context images' ) ;
}
let apiResponse ;
const geminiModel = process . env . GEMINI _IMAGE _MODEL || 'gemini-2.5-flash-image' ;
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
const config = {
responseModalities : [ 'TEXT' , 'IMAGE' ] ,
} ;
const supportsImageSize = ! geminiModel . includes ( 'gemini-2.5-flash-image' ) ;
if ( aspectRatio || ( imageSize && supportsImageSize ) ) {
config . imageConfig = { } ;
if ( aspectRatio ) {
config . imageConfig . aspectRatio = aspectRatio ;
2026-01-03 11:26:46 -05:00
}
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
if ( imageSize && supportsImageSize ) {
config . imageConfig . imageSize = imageSize ;
}
}
let derivedSignal = null ;
let abortHandler = null ;
2026-01-03 11:26:46 -05:00
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
if ( runnableConfig ? . signal ) {
derivedSignal = AbortSignal . any ( [ runnableConfig . signal ] ) ;
abortHandler = ( ) => logger . debug ( '[GeminiImageGen] Image generation aborted' ) ;
derivedSignal . addEventListener ( 'abort' , abortHandler , { once : true } ) ;
config . abortSignal = derivedSignal ;
}
try {
2026-01-03 11:26:46 -05:00
apiResponse = await ai . models . generateContent ( {
model : geminiModel ,
contents ,
config ,
} ) ;
} catch ( error ) {
logger . error ( '[GeminiImageGen] API error:' , error ) ;
return [
[ { type : ContentTypes . TEXT , text : ` Image generation failed: ${ error . message } ` } ] ,
{ content : [ ] , file _ids : [ ] } ,
] ;
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
} finally {
if ( abortHandler && derivedSignal ) {
derivedSignal . removeEventListener ( 'abort' , abortHandler ) ;
}
2026-01-03 11:26:46 -05:00
}
const safetyBlock = checkForSafetyBlock ( apiResponse ) ;
if ( safetyBlock ) {
logger . warn ( '[GeminiImageGen] Safety block:' , safetyBlock ) ;
const errorMsg = 'Image blocked by content safety filters. Please try different content.' ;
return [ [ { type : ContentTypes . TEXT , text : errorMsg } ] , { content : [ ] , file _ids : [ ] } ] ;
}
const rawImageData = apiResponse . candidates ? . [ 0 ] ? . content ? . parts ? . find ( ( p ) => p . inlineData )
? . inlineData ? . data ;
if ( ! rawImageData ) {
logger . warn ( '[GeminiImageGen] No image data in response' ) ;
return [
[ { type : ContentTypes . TEXT , text : 'No image was generated. Please try again.' } ] ,
{ content : [ ] , file _ids : [ ] } ,
] ;
}
const rawBuffer = Buffer . from ( rawImageData , 'base64' ) ;
const { buffer : convertedBuffer , format : outputFormat } = await convertImageFormat (
rawBuffer ,
imageOutputType ,
) ;
const imageData = convertedBuffer . toString ( 'base64' ) ;
const mimeType = outputFormat === 'jpeg' ? 'image/jpeg' : ` image/ ${ outputFormat } ` ;
const dataUrl = ` data: ${ mimeType } ;base64, ${ imageData } ` ;
const file _ids = [ v4 ( ) ] ;
const content = [
{
type : ContentTypes . IMAGE _URL ,
image _url : { url : dataUrl } ,
} ,
] ;
const textResponse = [
{
type : ContentTypes . TEXT ,
text :
displayMessage +
` \n \n generated_image_id: " ${ file _ids [ 0 ] } " ` +
( image _ids ? . length > 0 ? ` \n referenced_image_ids: [" ${ image _ids . join ( '", "' ) } "] ` : '' ) ,
} ,
] ;
💎 fix: Gemini Image Gen Tool Vertex AI Auth and File Storage (#11923)
* chore: saveToCloudStorage function and enhance error handling
- Removed unnecessary parameters and streamlined the logic for saving images to cloud storage.
- Introduced buffer handling for base64 image data and improved the integration with file strategy functions.
- Enhanced error handling during local image saving to ensure robustness.
- Updated the createGeminiImageTool function to reflect changes in the saveToCloudStorage implementation.
* refactor: streamline image persistence logic in GeminiImageGen
- Consolidated image saving functionality by renaming and refactoring the saveToCloudStorage function to persistGeneratedImage.
- Improved error handling and logging for image persistence operations.
- Enhanced the replaceUnwantedChars function to better sanitize input strings.
- Updated createGeminiImageTool to reflect changes in image handling and ensure consistent behavior across storage strategies.
* fix: clean up GeminiImageGen by removing unused functions and improving logging
- Removed the getSafeFormat and persistGeneratedImage functions to streamline image handling.
- Updated logging in createGeminiImageTool for clarity and consistency.
- Consolidated imports by eliminating unused dependencies, enhancing code maintainability.
* chore: update environment configuration and manifest for unused GEMINI_VERTEX_ENABLED
- Removed the Vertex AI configuration option from .env.example to simplify setup.
- Updated the manifest.json to reflect the removal of the Vertex AI dependency in the authentication field.
- Cleaned up the createGeminiImageTool function by eliminating unused fields related to Vertex AI, streamlining the code.
* fix: update loadAuthValues call in loadTools function for GeminiImageGen tool
- Modified the loadAuthValues function call to include throwError: false, preventing exceptions on authentication failures.
- Removed the unused processFileURL parameter from the tool context object, streamlining the code.
* refactor: streamline GoogleGenAI initialization in GeminiImageGen
- Removed unused file system access check for Google application credentials, simplifying the environment setup.
- Added googleAuthOptions to the GoogleGenAI instantiation, enhancing the configuration for authentication.
* fix: update Gemini API Key label and description in manifest.json
- Changed the label to indicate that the Gemini API Key is optional.
- Revised the description to clarify usage with Vertex AI and service accounts, enhancing user guidance.
* fix: enhance abort signal handling in createGeminiImageTool
- Introduced derivedSignal to manage abort events during image generation, improving responsiveness to cancellation requests.
- Added an abortHandler to log when image generation is aborted, enhancing debugging capabilities.
- Ensured proper cleanup of event listeners in the finally block to prevent memory leaks.
* fix: update authentication handling for plugins to support optional fields
- Added support for optional authentication fields in the manifest and PluginAuthForm.
- Updated the checkPluginAuth function to correctly validate plugins with optional fields.
- Enhanced tests to cover scenarios with optional authentication fields, ensuring accurate validation logic.
2026-02-24 08:21:02 -05:00
const conversationId = runnableConfig ? . configurable ? . thread _id ;
2026-01-03 11:26:46 -05:00
recordTokenUsage ( {
usageMetadata : apiResponse . usageMetadata ,
req ,
userId ,
conversationId ,
model : geminiModel ,
} ) . catch ( ( error ) => {
logger . error ( '[GeminiImageGen] Failed to record token usage:' , error ) ;
} ) ;
return [ textResponse , { content , file _ids } ] ;
} ,
{
... geminiToolkit . gemini _image _gen ,
responseFormat : 'content_and_artifact' ,
} ,
) ;
return geminiImageGenTool ;
}
// Export both for compatibility
module . exports = createGeminiImageTool ;
module . exports . createGeminiImageTool = createGeminiImageTool ;