mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-25 11:54:08 +01: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.
This commit is contained in:
parent
1d0a4c501f
commit
f3eb197675
8 changed files with 136 additions and 181 deletions
|
|
@ -189,6 +189,77 @@ describe('format.ts helper functions', () => {
|
|||
const result = checkPluginAuth(plugin);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when auth field is marked as optional with no env vars', () => {
|
||||
const plugin: TPlugin = {
|
||||
name: 'Test',
|
||||
pluginKey: 'test',
|
||||
description: 'Test plugin',
|
||||
authConfig: [
|
||||
{ authField: 'MISSING_KEY', label: 'API Key', description: 'API Key', optional: true },
|
||||
],
|
||||
};
|
||||
|
||||
const result = checkPluginAuth(plugin);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when all auth fields are optional', () => {
|
||||
const plugin: TPlugin = {
|
||||
name: 'Test',
|
||||
pluginKey: 'test',
|
||||
description: 'Test plugin',
|
||||
authConfig: [
|
||||
{ authField: 'MISSING_KEY_A', label: 'Key A', description: 'Key A', optional: true },
|
||||
{ authField: 'MISSING_KEY_B', label: 'Key B', description: 'Key B', optional: true },
|
||||
],
|
||||
};
|
||||
|
||||
const result = checkPluginAuth(plugin);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when required field is missing even if optional field exists', () => {
|
||||
const plugin: TPlugin = {
|
||||
name: 'Test',
|
||||
pluginKey: 'test',
|
||||
description: 'Test plugin',
|
||||
authConfig: [
|
||||
{ authField: 'MISSING_KEY', label: 'Required Key', description: 'Required' },
|
||||
{
|
||||
authField: 'OPTIONAL_KEY',
|
||||
label: 'Optional Key',
|
||||
description: 'Optional',
|
||||
optional: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = checkPluginAuth(plugin);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when optional field has no env var but required field is satisfied', () => {
|
||||
process.env.REQUIRED_KEY = 'valid-key';
|
||||
|
||||
const plugin: TPlugin = {
|
||||
name: 'Test',
|
||||
pluginKey: 'test',
|
||||
description: 'Test plugin',
|
||||
authConfig: [
|
||||
{ authField: 'REQUIRED_KEY', label: 'Required Key', description: 'Required' },
|
||||
{
|
||||
authField: 'OPTIONAL_KEY',
|
||||
label: 'Optional Key',
|
||||
description: 'Optional',
|
||||
optional: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result = checkPluginAuth(plugin);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getToolkitKey', () => {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ export const checkPluginAuth = (plugin?: TPlugin): boolean => {
|
|||
}
|
||||
|
||||
return plugin.authConfig.every((authFieldObj) => {
|
||||
if (authFieldObj.optional === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const authFieldOptions = authFieldObj.authField.split('||');
|
||||
let isFieldAuthenticated = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -544,6 +544,7 @@ export const tPluginAuthConfigSchema = z.object({
|
|||
authField: z.string(),
|
||||
label: z.string(),
|
||||
description: z.string(),
|
||||
optional: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type TPluginAuthConfig = z.infer<typeof tPluginAuthConfigSchema>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue