🛡️ feat: Google Reverse Proxy support, CIVIC_INTEGRITY harm category (#5037)

* 🛡️ feat: Google Reverse Proxy support, `CIVIC_INTEGRITY` harm category

* 🔧 chore: Update @langchain/google-vertexai to version 0.1.4 in package.json and package-lock.json

* fix: revert breaking Vertex AI changes

---------

Co-authored-by: KiGamji <maloyh44@gmail.com>
This commit is contained in:
Danny Avila 2024-12-18 12:13:16 -05:00 committed by GitHub
parent 22a87b6162
commit 3ceb227507
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 98 additions and 53 deletions

View file

@ -138,7 +138,10 @@ BINGAI_TOKEN=user_provided
#============#
GOOGLE_KEY=user_provided
# GOOGLE_REVERSE_PROXY=
# Some reverse proxies do not support the X-goog-api-key header, uncomment to pass the API key in Authorization header instead.
# GOOGLE_AUTH_HEADER=true
# Gemini API (AI Studio)
# GOOGLE_MODELS=gemini-2.0-flash-exp,gemini-exp-1121,gemini-exp-1114,gemini-1.5-flash-latest,gemini-1.0-pro,gemini-1.0-pro-001,gemini-1.0-pro-latest,gemini-1.0-pro-vision-latest,gemini-1.5-pro-latest,gemini-pro,gemini-pro-vision
@ -167,6 +170,7 @@ GOOGLE_KEY=user_provided
# GOOGLE_SAFETY_HATE_SPEECH=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_HARASSMENT=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_DANGEROUS_CONTENT=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_CIVIC_INTEGRITY=BLOCK_ONLY_HIGH
#============#
# OpenAI #

View file

@ -30,8 +30,7 @@ const BaseClient = require('./BaseClient');
const loc = process.env.GOOGLE_LOC || 'us-central1';
const publisher = 'google';
const endpointPrefix = `https://${loc}-aiplatform.googleapis.com`;
// const apiEndpoint = loc + '-aiplatform.googleapis.com';
const endpointPrefix = `${loc}-aiplatform.googleapis.com`;
const tokenizersCache = {};
const settings = endpointSettings[EModelEndpoint.google];
@ -58,6 +57,10 @@ class GoogleClient extends BaseClient {
this.apiKey = creds[AuthKeys.GOOGLE_API_KEY];
this.reverseProxyUrl = options.reverseProxyUrl;
this.authHeader = options.authHeader;
if (options.skipSetOptions) {
return;
}
@ -66,7 +69,7 @@ class GoogleClient extends BaseClient {
/* Google specific methods */
constructUrl() {
return `${endpointPrefix}/v1/projects/${this.project_id}/locations/${loc}/publishers/${publisher}/models/${this.modelOptions.model}:serverStreamingPredict`;
return `https://${endpointPrefix}/v1/projects/${this.project_id}/locations/${loc}/publishers/${publisher}/models/${this.modelOptions.model}:serverStreamingPredict`;
}
async getClient() {
@ -595,7 +598,21 @@ class GoogleClient extends BaseClient {
createLLM(clientOptions) {
const model = clientOptions.modelName ?? clientOptions.model;
clientOptions.location = loc;
clientOptions.endpoint = `${loc}-aiplatform.googleapis.com`;
clientOptions.endpoint = endpointPrefix;
let requestOptions = null;
if (this.reverseProxyUrl) {
requestOptions = {
baseUrl: this.reverseProxyUrl,
};
if (this.authHeader) {
requestOptions.customHeaders = {
Authorization: `Bearer ${this.apiKey}`,
};
}
}
if (this.project_id && this.isTextModel) {
logger.debug('Creating Google VertexAI client');
return new GoogleVertexAI(clientOptions);
@ -607,10 +624,7 @@ class GoogleClient extends BaseClient {
return new ChatVertexAI(clientOptions);
} else if (!EXCLUDED_GENAI_MODELS.test(model)) {
logger.debug('Creating GenAI client');
return new GenAI(this.apiKey).getGenerativeModel({
...clientOptions,
model,
});
return new GenAI(this.apiKey).getGenerativeModel({ ...clientOptions, model }, requestOptions);
}
logger.debug('Creating Chat Google Generative AI client');
@ -901,6 +915,10 @@ class GoogleClient extends BaseClient {
threshold:
process.env.GOOGLE_SAFETY_DANGEROUS_CONTENT || 'HARM_BLOCK_THRESHOLD_UNSPECIFIED',
},
{
category: 'HARM_CATEGORY_CIVIC_INTEGRITY',
threshold: process.env.GOOGLE_SAFETY_CIVIC_INTEGRITY || 'HARM_BLOCK_THRESHOLD_UNSPECIFIED',
},
];
}

View file

@ -42,7 +42,7 @@
"@langchain/community": "^0.3.14",
"@langchain/core": "^0.3.18",
"@langchain/google-genai": "^0.1.4",
"@langchain/google-vertexai": "^0.1.2",
"@langchain/google-vertexai": "^0.1.4",
"@langchain/textsplitters": "^0.1.0",
"@librechat/agents": "^1.8.8",
"axios": "^1.7.7",

View file

@ -1,9 +1,15 @@
const { EModelEndpoint, AuthKeys } = require('librechat-data-provider');
const { getUserKey, checkUserKeyExpiry } = require('~/server/services/UserService');
const { GoogleClient } = require('~/app');
const { isEnabled } = require('~/server/utils');
const initializeClient = async ({ req, res, endpointOption }) => {
const { GOOGLE_KEY, GOOGLE_REVERSE_PROXY, PROXY } = process.env;
const {
GOOGLE_KEY,
GOOGLE_REVERSE_PROXY,
GOOGLE_AUTH_HEADER,
PROXY,
} = process.env;
const isUserProvided = GOOGLE_KEY === 'user_provided';
const { key: expiresAt } = req.body;
@ -46,6 +52,7 @@ const initializeClient = async ({ req, res, endpointOption }) => {
req,
res,
reverseProxyUrl: GOOGLE_REVERSE_PROXY ?? null,
authHeader: isEnabled(GOOGLE_AUTH_HEADER) ?? null,
proxy: PROXY ?? null,
...clientOptions,
...endpointOption,

102
package-lock.json generated
View file

@ -51,7 +51,7 @@
"@langchain/community": "^0.3.14",
"@langchain/core": "^0.3.18",
"@langchain/google-genai": "^0.1.4",
"@langchain/google-vertexai": "^0.1.2",
"@langchain/google-vertexai": "^0.1.4",
"@langchain/textsplitters": "^0.1.0",
"@librechat/agents": "^1.8.8",
"axios": "^1.7.7",
@ -682,6 +682,20 @@
"@langchain/core": ">=0.3.17 <0.4.0"
}
},
"api/node_modules/@langchain/google-vertexai": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@langchain/google-vertexai/-/google-vertexai-0.1.4.tgz",
"integrity": "sha512-x78wezYBOxmiMOPSatlCk4UOQd6RPxz2YVfGKLOzNV89xxHrEVX9JcyRUCx4L568S4kqZYkLvnqzZA9AF/TCaA==",
"dependencies": {
"@langchain/google-gauth": "~0.1.4"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"api/node_modules/@langchain/textsplitters": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@langchain/textsplitters/-/textsplitters-0.1.0.tgz",
@ -9835,6 +9849,48 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/@langchain/google-common": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@langchain/google-common/-/google-common-0.1.4.tgz",
"integrity": "sha512-EIpJYhat+BpGXRJiLSKKWlbBl88AJLnwGhLNOh85nNPtcqKqWTIJ/WGVNfFNsrAwHZ+f77gZeNfefeRIrChNZw==",
"dependencies": {
"uuid": "^10.0.0",
"zod-to-json-schema": "^3.22.4"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"node_modules/@langchain/google-common/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@langchain/google-gauth": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@langchain/google-gauth/-/google-gauth-0.1.4.tgz",
"integrity": "sha512-g/yXfGCgBU5FkH/lW4L0E2HDvQ3JuS5/KZylixWwkV+hk9gSyYcMV3RnhMjp+zEY/68XALiqlwUyvfK5vToz4g==",
"dependencies": {
"@langchain/google-common": "~0.1.4",
"google-auth-library": "^8.9.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"node_modules/@langchain/google-genai": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/@langchain/google-genai/-/google-genai-0.0.11.tgz",
@ -9931,6 +9987,8 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@langchain/google-vertexai/-/google-vertexai-0.1.2.tgz",
"integrity": "sha512-b8Di2AgSwlyyKl4A5qii+19Wj82I1KvtUXSDvJpDzhucuyrJjmnNb/0ClkaIQv6RyISajtxszxxSGHukPn3PJA==",
"optional": true,
"peer": true,
"dependencies": {
"@langchain/google-gauth": "~0.1.2"
},
@ -9941,48 +9999,6 @@
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"node_modules/@langchain/google-vertexai/node_modules/@langchain/google-common": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@langchain/google-common/-/google-common-0.1.2.tgz",
"integrity": "sha512-3A7vUr2WObCFUusM/Wl0yZN7QGGXboXyparORkZdv0RnGngPm6tBmqbAyWYmT8R9aQNHqzBKDEQBiSRvTxao1w==",
"dependencies": {
"uuid": "^10.0.0",
"zod-to-json-schema": "^3.22.4"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"node_modules/@langchain/google-vertexai/node_modules/@langchain/google-gauth": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@langchain/google-gauth/-/google-gauth-0.1.2.tgz",
"integrity": "sha512-5fPPaVcv4l2o/WdPuFLkIKFsfAeY8JD7zP/lFlTTeDvCbGbnsywwX08ZCqe9jgDIVBGcIoUqhiyBvwrpJMzMEw==",
"dependencies": {
"@langchain/google-common": "~0.1.2",
"google-auth-library": "^8.9.0"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@langchain/core": ">=0.2.21 <0.4.0"
}
},
"node_modules/@langchain/google-vertexai/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@langchain/langgraph": {
"version": "0.2.33",
"resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-0.2.33.tgz",