Vertex: Add Vertex AI-specific safety setting (#4770) Closes #4455

1baaa26729b173afde7df3ca844a2d7add939fb6

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
3 files changed, +33 -8Showing whitespace changes
src/constants.js+23 -0
@@ -161,6 +161,29 @@ export const GEMINI_SAFETY = [
161161 },
162162];
163163
164+export const VERTEX_SAFETY = [
165+ {
166+ category: 'HARM_CATEGORY_IMAGE_HATE',
167+ threshold: 'OFF',
168+ },
169+ {
170+ category: 'HARM_CATEGORY_IMAGE_DANGEROUS_CONTENT',
171+ threshold: 'OFF',
172+ },
173+ {
174+ category: 'HARM_CATEGORY_IMAGE_HARASSMENT',
175+ threshold: 'OFF',
176+ },
177+ {
178+ category: 'HARM_CATEGORY_IMAGE_SEXUALLY_EXPLICIT',
179+ threshold: 'OFF',
180+ },
181+ {
182+ category: 'HARM_CATEGORY_JAILBREAK',
183+ threshold: 'OFF',
184+ },
185+];
186+
164187export const CHAT_COMPLETION_SOURCES = {
165188 OPENAI: 'openai',
166189 CLAUDE: 'claude',
src/endpoints/backends/chat-completions.js+2 -1
@@ -12,6 +12,7 @@ import {
1212 OPENAI_REASONING_EFFORT_MAP,
1313 OPENAI_REASONING_EFFORT_MODELS,
1414 OPENROUTER_HEADERS,
15+ VERTEX_SAFETY,
1516} from '../../constants.js';
1617import {
1718 forwardFetchResponse,
@@ -405,7 +406,7 @@ async function sendMakerSuiteRequest(request, response) {
405406
406407 const tools = [];
407408 const prompt = convertGooglePrompt(request.body.messages, model, useSystemPrompt, getPromptNames(request));
408- let safetySettings = GEMINI_SAFETY;
409+ const safetySettings = [...GEMINI_SAFETY, ...(useVertexAi ? VERTEX_SAFETY : [])];
409410
410411 if (enableWebSearch && !enableImageModality && !isGemma && !isLearnLM && !noSearchModels.includes(model)) {
411412 tools.push({ google_search: {} });
src/endpoints/google.js+8 -7
@@ -8,7 +8,7 @@ import urlJoin from 'url-join';
88import lodash from 'lodash';
99
1010import { readSecret, SECRET_KEYS } from './secrets.js';
1111import { GEMINI_SAFETY, VERTEX_SAFETY } from '../constants.js';
1212import { delay, getConfigValue, trimTrailingSlash } from '../util.js';
1313
1414const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
@@ -159,12 +159,13 @@ export function getProjectIdFromServiceAccount(serviceAccount) {
159159 * @param {express.Request} request Express request object
160160 * @param {string} model Model name to use
161161 * @param {string} endpoint API endpoint (default: 'generateContent')
162162 * @returns {Promise<{url: string, headers: object, apiName: string, baseUrl: string, safetySettings: object[]}>} URL, headers, and API name
163163 */
164164export async function getGoogleApiConfig(request, model, endpoint = 'generateContent') {
165165 const useVertexAi = request.body.api === 'vertexai';
166166 const region = request.body.vertexai_region || 'us-central1';
167167 const apiName = useVertexAi ? 'Google Vertex AI' : 'Google AI Studio';
168+ const safetySettings = [...GEMINI_SAFETY, ...(useVertexAi ? VERTEX_SAFETY : [])];
168169
169170 let url;
170171 let baseUrl;
@@ -225,7 +226,7 @@ export async function getGoogleApiConfig(request, model, endpoint = 'generateCon
225226 headers['x-goog-api-key'] = apiKey;
226227 }
227228
228229 return { url, headers, apiName, baseUrl, safetySettings };
229230}
230231
231232export const router = express.Router();
@@ -235,7 +236,7 @@ router.post('/caption-image', async (request, response) => {
235236 const mimeType = request.body.image.split(';')[0].split(':')[1];
236237 const base64Data = request.body.image.split(',')[1];
237238 const model = request.body.model || 'gemini-2.0-flash';
238239 const { url, headers, apiName, safetySettings } = await getGoogleApiConfig(request, model);
239240
240241 const body = {
241242 contents: [{
@@ -249,7 +250,7 @@ router.post('/caption-image', async (request, response) => {
249250 },
250251 }],
251252 }],
252253 safetySettings: GEMINI_SAFETYsafetySettings,
253254 };
254255
255256 console.debug(`${apiName} captioning request`, model, body);
@@ -355,7 +356,7 @@ router.post('/list-native-voices', async (_, response) => {
355356router.post('/generate-native-tts', async (request, response) => {
356357 try {
357358 const { text, voice, model } = request.body;
358359 const { url, headers, apiName, safetySettings } = await getGoogleApiConfig(request, model);
359360
360361 console.debug(`${apiName} TTS request`, { model, text, voice });
361362
@@ -374,7 +375,7 @@ router.post('/generate-native-tts', async (request, response) => {
374375 },
375376 },
376377 },
377378 safetySettings: GEMINI_SAFETYsafetySettings,
378379 };
379380
380381 const result = await fetch(url, {