💄 style: add region support for Vertex AI provider (#9720)

 feat: add region support for Vertex AI provider

- Add VertexAIKeyVault interface with region support
- Update UI to include region selector with 35+ regions
- Add vertexAIRegion field to ClientSecretPayload
- Update backend to use user-selected region with fallback
- Add i18n support for English and Chinese
- Fix issue with Gemini 2.5 models requiring global region
This commit is contained in:
Arvin Xu
2025-10-15 16:39:36 +02:00
committed by GitHub
parent 0a8c80dfd2
commit d17b50c6dc
8 changed files with 96 additions and 5 deletions

View File

@@ -399,6 +399,11 @@
"desc": "Enter your Vertex AI Keys",
"placeholder": "{ \"type\": \"service_account\", \"project_id\": \"xxx\", \"private_key_id\": ... }",
"title": "Vertex AI Keys"
},
"region": {
"desc": "Select the region for Vertex AI service. Some models like Gemini 2.5 are only available in specific regions (e.g., global)",
"placeholder": "Select region",
"title": "Vertex AI Region"
}
},
"zeroone": {

View File

@@ -399,6 +399,11 @@
"desc": "填入你的 Vertex Ai Keys",
"placeholder": "{ \"type\": \"service_account\", \"project_id\": \"xxx\", \"private_key_id\": ... }",
"title": "Vertex AI Keys"
},
"region": {
"desc": "选择 Vertex AI 服务的区域。某些模型如 Gemini 2.5 仅在特定区域可用(如 global",
"placeholder": "选择区域",
"title": "Vertex AI 区域"
}
},
"zeroone": {

View File

@@ -27,6 +27,8 @@ export interface ClientSecretPayload {
cloudflareBaseURLOrAccountID?: string;
vertexAIRegion?: string;
/**
* user id
* in client db mode it's a uuid

View File

@@ -24,6 +24,11 @@ export interface AWSBedrockKeyVault {
sessionToken?: string;
}
export interface VertexAIKeyVault {
apiKey?: string;
region?: string;
}
export interface CloudflareKeyVault {
apiKey?: string;
baseURLOrAccountID?: string;
@@ -96,7 +101,7 @@ export interface UserKeyVaults extends SearchEngineKeyVaults {
upstage?: OpenAICompatibleKeyVault;
v0?: OpenAICompatibleKeyVault;
vercelaigateway?: OpenAICompatibleKeyVault;
vertexai?: OpenAICompatibleKeyVault;
vertexai?: VertexAIKeyVault;
vllm?: OpenAICompatibleKeyVault;
volcengine?: OpenAICompatibleKeyVault;
wenxin?: OpenAICompatibleKeyVault;

View File

@@ -1,6 +1,6 @@
'use client';
import { Markdown } from '@lobehub/ui';
import { Markdown, Select } from '@lobehub/ui';
import { createStyles } from 'antd-style';
import { useTranslation } from 'react-i18next';
@@ -28,6 +28,48 @@ const useStyles = createStyles(({ css, token }) => ({
const providerKey: GlobalLLMProviderKey = 'vertexai';
const VERTEX_AI_REGIONS: string[] = [
'global',
'us-central1',
'us-east1',
'us-east4',
'us-west1',
'us-west2',
'us-west3',
'us-west4',
'us-south1',
'northamerica-northeast1',
'northamerica-northeast2',
'southamerica-east1',
'southamerica-west1',
'europe-central2',
'europe-north1',
'europe-southwest1',
'europe-west1',
'europe-west2',
'europe-west3',
'europe-west4',
'europe-west6',
'europe-west8',
'europe-west9',
'europe-west10',
'europe-west12',
'me-central1',
'me-central2',
'me-west1',
'africa-south1',
'asia-east1',
'asia-east2',
'asia-northeast1',
'asia-northeast2',
'asia-northeast3',
'asia-south1',
'asia-southeast1',
'asia-southeast2',
'australia-southeast1',
'australia-southeast2',
];
// Same as OpenAIProvider, but replace API Key with HuggingFace Access Token
const useProviderCard = (): ProviderItem => {
const { t } = useTranslation('modelProvider');
@@ -54,6 +96,27 @@ const useProviderCard = (): ProviderItem => {
label: t('vertexai.apiKey.title'),
name: [KeyVaultsConfigKey, LLMProviderApiTokenKey],
},
{
children: isLoading ? (
<SkeletonInput />
) : (
<Select
allowClear
options={VERTEX_AI_REGIONS.map((region) => ({
label: region,
value: region,
}))}
placeholder={t('vertexai.region.placeholder')}
/>
),
desc: (
<Markdown className={styles.markdown} fontSize={12} variant={'chat'}>
{t('vertexai.region.desc')}
</Markdown>
),
label: t('vertexai.region.title'),
name: [KeyVaultsConfigKey, 'region'],
},
],
};
};

View File

@@ -407,6 +407,11 @@ export default {
placeholder: `{ "type": "service_account", "project_id": "xxx", "private_key_id": ... }`,
title: 'Vertex AI Keys',
},
region: {
desc: '选择 Vertex AI 服务的区域。某些模型如 Gemini 2.5 仅在特定区域可用(如 global',
placeholder: '选择区域',
title: 'Vertex AI 区域',
},
},
zeroone: {
title: '01.AI 零一万物',

View File

@@ -136,7 +136,7 @@ const buildVertexOptions = (
const project = projectFromParams ?? projectFromCredentials ?? projectFromEnv;
const location =
(params.location as string | undefined) ?? process.env.VERTEXAI_LOCATION ?? undefined;
(params.location as string | undefined) ?? payload.vertexAIRegion ?? process.env.VERTEXAI_LOCATION ?? undefined;
const googleAuthOptions = params.googleAuthOptions ?? (credentials ? { credentials } : undefined);

View File

@@ -5,6 +5,7 @@ import {
ClientSecretPayload,
CloudflareKeyVault,
OpenAICompatibleKeyVault,
VertexAIKeyVault,
} from '@lobechat/types';
import { clientApiKeyManager } from '@lobechat/utils/client';
import { ModelProvider } from 'model-bank';
@@ -21,7 +22,8 @@ export const getProviderAuthPayload = (
keyVaults: OpenAICompatibleKeyVault &
AzureOpenAIKeyVault &
AWSBedrockKeyVault &
CloudflareKeyVault,
CloudflareKeyVault &
VertexAIKeyVault,
) => {
switch (provider) {
case ModelProvider.Bedrock: {
@@ -76,7 +78,11 @@ export const getProviderAuthPayload = (
case ModelProvider.VertexAI: {
// Vertex AI uses JSON credentials, should not split by comma
return { apiKey: keyVaults?.apiKey, baseURL: keyVaults?.baseURL };
return {
apiKey: keyVaults?.apiKey,
baseURL: keyVaults?.baseURL,
vertexAIRegion: keyVaults?.region,
};
}
default: {