mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-27 21:58:51 +01:00
🚀 fix: Resolve Google Client Issues, CDN Screenshots, Update Models (#5703)
* 🤖 refactor: streamline model selection logic for title model in GoogleClient
* refactor: add options for empty object schemas in convertJsonSchemaToZod
* refactor: add utility function to check for empty object schemas in convertJsonSchemaToZod
* fix: Google MCP Tool errors, and remove Object Unescaping as Google fixed this
* fix: google safetySettings
* feat: add safety settings exclusion via GOOGLE_EXCLUDE_SAFETY_SETTINGS environment variable
* fix: rename environment variable for console JSON string length
* fix: disable portal for dropdown in ExportModal component
* fix: screenshot functionality to use image placeholder for remote images
* feat: add visionMode property to BaseClient and initialize in GoogleClient to fix resendFiles issue
* fix: enhance formatMessages to include image URLs in message content for Vertex AI
* fix: safety settings for titleChatCompletion
* fix: remove deprecated model assignment in GoogleClient and streamline title model retrieval
* fix: remove unused image preloading logic in ScreenshotContext
* chore: update default google models to latest models shared by vertex ai and gen ai
* refactor: enhance Google error messaging
* fix: update token values and model limits for Gemini models
* ci: fix model matching
* chore: bump version of librechat-data-provider to 0.7.699
This commit is contained in:
parent
33e60c379b
commit
63afb317c6
19 changed files with 939 additions and 720 deletions
|
|
@ -1,18 +1,42 @@
|
|||
const { Providers } = require('@librechat/agents');
|
||||
const { AuthKeys } = require('librechat-data-provider');
|
||||
const { isEnabled } = require('~/server/utils');
|
||||
|
||||
function getThresholdMapping(model) {
|
||||
const gemini1Pattern = /gemini-(1\.0|1\.5|pro$|1\.0-pro|1\.5-pro|1\.5-flash-001)/;
|
||||
const restrictedPattern = /(gemini-(1\.5-flash-8b|2\.0|exp)|learnlm)/;
|
||||
|
||||
if (gemini1Pattern.test(model)) {
|
||||
return (value) => {
|
||||
if (value === 'OFF') {
|
||||
return 'BLOCK_NONE';
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
if (restrictedPattern.test(model)) {
|
||||
return (value) => {
|
||||
if (value === 'OFF' || value === 'HARM_BLOCK_THRESHOLD_UNSPECIFIED') {
|
||||
return 'BLOCK_NONE';
|
||||
}
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
return (value) => value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {boolean} isGemini2
|
||||
* @returns {Array<{category: string, threshold: string}>}
|
||||
* @param {string} model
|
||||
* @returns {Array<{category: string, threshold: string}> | undefined}
|
||||
*/
|
||||
function getSafetySettings(isGemini2) {
|
||||
const mapThreshold = (value) => {
|
||||
if (isGemini2 && value === 'BLOCK_NONE') {
|
||||
return 'OFF';
|
||||
}
|
||||
return value;
|
||||
};
|
||||
function getSafetySettings(model) {
|
||||
if (isEnabled(process.env.GOOGLE_EXCLUDE_SAFETY_SETTINGS)) {
|
||||
return undefined;
|
||||
}
|
||||
const mapThreshold = getThresholdMapping(model);
|
||||
|
||||
return [
|
||||
{
|
||||
|
|
@ -85,8 +109,7 @@ function getLLMConfig(credentials, options = {}) {
|
|||
};
|
||||
|
||||
/** Used only for Safety Settings */
|
||||
const isGemini2 = llmConfig.model.includes('gemini-2.0') && !llmConfig.model.includes('thinking');
|
||||
llmConfig.safetySettings = getSafetySettings(isGemini2);
|
||||
llmConfig.safetySettings = getSafetySettings(llmConfig.model);
|
||||
|
||||
let provider;
|
||||
|
||||
|
|
@ -153,4 +176,5 @@ function getLLMConfig(credentials, options = {}) {
|
|||
|
||||
module.exports = {
|
||||
getLLMConfig,
|
||||
getSafetySettings,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
const { CacheKeys, Constants } = require('librechat-data-provider');
|
||||
const { EModelEndpoint, CacheKeys, Constants, googleSettings } = require('librechat-data-provider');
|
||||
const getLogStores = require('~/cache/getLogStores');
|
||||
const initializeClient = require('./initialize');
|
||||
const { isEnabled } = require('~/server/utils');
|
||||
const { saveConvo } = require('~/models');
|
||||
const { logger } = require('~/config');
|
||||
const initializeClient = require('./initialize');
|
||||
|
||||
const addTitle = async (req, { text, response, client }) => {
|
||||
const { TITLE_CONVO = 'true' } = process.env ?? {};
|
||||
|
|
@ -14,22 +13,16 @@ const addTitle = async (req, { text, response, client }) => {
|
|||
if (client.options.titleConvo === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
const DEFAULT_TITLE_MODEL = 'gemini-pro';
|
||||
const { GOOGLE_TITLE_MODEL } = process.env ?? {};
|
||||
|
||||
let model = GOOGLE_TITLE_MODEL ?? DEFAULT_TITLE_MODEL;
|
||||
const providerConfig = req.app.locals[EModelEndpoint.google];
|
||||
let model =
|
||||
providerConfig?.titleModel ??
|
||||
GOOGLE_TITLE_MODEL ??
|
||||
client.options?.modelOptions.model ??
|
||||
googleSettings.model.default;
|
||||
|
||||
if (GOOGLE_TITLE_MODEL === Constants.CURRENT_MODEL) {
|
||||
model = client.options?.modelOptions.model;
|
||||
|
||||
if (client.isVisionModel) {
|
||||
logger.warn(
|
||||
`current_model was specified for Google title request, but the model ${model} cannot process a text-only conversation. Falling back to ${DEFAULT_TITLE_MODEL}`,
|
||||
);
|
||||
|
||||
model = DEFAULT_TITLE_MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
const titleEndpointOptions = {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
const { z } = require('zod');
|
||||
const { tool } = require('@langchain/core/tools');
|
||||
const { Constants: AgentConstants } = require('@librechat/agents');
|
||||
const { Constants: AgentConstants, Providers } = require('@librechat/agents');
|
||||
const {
|
||||
Constants,
|
||||
convertJsonSchemaToZod,
|
||||
ContentTypes,
|
||||
isAssistantsEndpoint,
|
||||
convertJsonSchemaToZod,
|
||||
} = require('librechat-data-provider');
|
||||
const { logger, getMCPManager } = require('~/config');
|
||||
|
||||
|
|
@ -25,7 +27,15 @@ async function createMCPTool({ req, toolKey, provider }) {
|
|||
}
|
||||
/** @type {LCTool} */
|
||||
const { description, parameters } = toolDefinition;
|
||||
const schema = convertJsonSchemaToZod(parameters);
|
||||
const isGoogle = provider === Providers.VERTEXAI || provider === Providers.GOOGLE;
|
||||
let schema = convertJsonSchemaToZod(parameters, {
|
||||
allowEmptyObject: !isGoogle,
|
||||
});
|
||||
|
||||
if (!schema) {
|
||||
schema = z.object({ input: z.string().optional() });
|
||||
}
|
||||
|
||||
const [toolName, serverName] = toolKey.split(Constants.mcp_delimiter);
|
||||
/** @type {(toolInput: Object | string) => Promise<unknown>} */
|
||||
const _call = async (toolInput) => {
|
||||
|
|
@ -35,6 +45,9 @@ async function createMCPTool({ req, toolKey, provider }) {
|
|||
if (isAssistantsEndpoint(provider) && Array.isArray(result)) {
|
||||
return result[0];
|
||||
}
|
||||
if (isGoogle && Array.isArray(result[0]) && result[0][0]?.type === ContentTypes.TEXT) {
|
||||
return [result[0][0].text, result[1]];
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error(`${toolName} MCP server tool call failed`, error);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue