From 657019a5a99fc639c284d9e1891858335901a490 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 19 Jul 2024 18:36:49 +0800 Subject: [PATCH] feat: support AWS Bedrock #308 (#1617) ### What problem does this PR solve? feat: support AWS Bedrock #308 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/locales/en.ts | 14 +++ web/src/locales/zh-traditional.ts | 14 +++ web/src/locales/zh.ts | 14 +++ .../setting-model/bedrock-modal/index.tsx | 119 ++++++++++++++++++ .../user-setting/setting-model/constant.ts | 33 +++++ .../pages/user-setting/setting-model/hooks.ts | 37 ++++-- .../user-setting/setting-model/index.tsx | 79 ++++++------ .../index.tsx | 0 8 files changed, 258 insertions(+), 52 deletions(-) create mode 100644 web/src/pages/user-setting/setting-model/bedrock-modal/index.tsx create mode 100644 web/src/pages/user-setting/setting-model/constant.ts rename web/src/pages/user-setting/setting-model/{volcengine-model => volcengine-modal}/index.tsx (100%) diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 2cad09673..ad2c23e4f 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -492,6 +492,20 @@ The above is the content you need to summarize.`, volcAKMessage: 'Please input your VOLC_ACCESS_KEY', addVolcEngineSK: 'VOLC SECRET_KEY', volcSKMessage: 'Please input your SECRET_KEY', + bedrockModelNameMessage: 'Please input your model name!', + addBedrockEngineAK: 'ACCESS KEY', + bedrockAKMessage: 'Please input your ACCESS KEY', + addBedrockSK: 'SECRET KEY', + bedrockSKMessage: 'Please input your SECRET KEY', + bedrockRegion: 'AWS Region', + bedrockRegionMessage: 'Please select!', + 'us-east-1': 'US East (N. Virginia)', + 'us-west-2': 'US West (Oregon)', + 'ap-southeast-1': 'Asia Pacific (Singapore)', + 'ap-northeast-1': 'Asia Pacific (Tokyo)', + 'eu-central-1': 'Europe (Frankfurt)', + 'us-gov-west-1': 'AWS GovCloud (US-West)', + 'ap-southeast-2': 'Asia Pacific (Sydney)', }, message: { registered: 'Registered!', diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index 40e6fbb1a..d27f63a1a 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -455,6 +455,20 @@ export default { volcAKMessage: '請輸入VOLC_ACCESS_KEY', addVolcEngineSK: '火山 SECRET_KEY', volcSKMessage: '請輸入VOLC_SECRET_KEY', + bedrockModelNameMessage: '請輸入名稱!', + addBedrockEngineAK: 'ACCESS KEY', + bedrockAKMessage: '請輸入 ACCESS KEY', + addBedrockSK: 'SECRET KEY', + bedrockSKMessage: '請輸入 SECRET KEY', + bedrockRegion: 'AWS Region', + bedrockRegionMessage: '請選擇!', + 'us-east-1': '美國東部 (維吉尼亞北部)', + 'us-west-2': '美國西部 (俄勒岡州)', + 'ap-southeast-1': '亞太地區 (新加坡)', + 'ap-northeast-1': '亞太地區 (東京)', + 'eu-central-1': '歐洲 (法蘭克福)', + 'us-gov-west-1': 'AWS GovCloud (US-West)', + 'ap-southeast-2': '亞太地區 (雪梨)', }, message: { registered: '註冊成功', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 116c9613c..12ff68d00 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -472,6 +472,20 @@ export default { volcAKMessage: '请输入VOLC_ACCESS_KEY', addVolcEngineSK: '火山 SECRET_KEY', volcSKMessage: '请输入VOLC_SECRET_KEY', + bedrockModelNameMessage: '请输入名称!', + addBedrockEngineAK: 'ACCESS KEY', + bedrockAKMessage: '请输入 ACCESS KEY', + addBedrockSK: 'SECRET KEY', + bedrockSKMessage: '请输入 SECRET KEY', + bedrockRegion: 'AWS Region', + bedrockRegionMessage: '请选择!', + 'us-east-1': '美国东部 (弗吉尼亚北部)', + 'us-west-2': '美国西部 (俄勒冈州)', + 'ap-southeast-1': '亚太地区 (新加坡)', + 'ap-northeast-1': '亚太地区 (东京)', + 'eu-central-1': '欧洲 (法兰克福)', + 'us-gov-west-1': 'AWS GovCloud (US-West)', + 'ap-southeast-2': '亚太地区 (悉尼)', }, message: { registered: '注册成功', diff --git a/web/src/pages/user-setting/setting-model/bedrock-modal/index.tsx b/web/src/pages/user-setting/setting-model/bedrock-modal/index.tsx new file mode 100644 index 000000000..4a137056b --- /dev/null +++ b/web/src/pages/user-setting/setting-model/bedrock-modal/index.tsx @@ -0,0 +1,119 @@ +import { useTranslate } from '@/hooks/common-hooks'; +import { IModalProps } from '@/interfaces/common'; +import { IAddLlmRequestBody } from '@/interfaces/request/llm'; +import { Flex, Form, Input, Modal, Select, Space } from 'antd'; +import { useMemo } from 'react'; +import { BedrockRegionList } from '../constant'; + +type FieldType = IAddLlmRequestBody & { + bedrock_ak: string; + bedrock_sk: string; + bedrock_region: string; +}; + +const { Option } = Select; + +const BedrockModal = ({ + visible, + hideModal, + onOk, + loading, + llmFactory, +}: IModalProps & { llmFactory: string }) => { + const [form] = Form.useForm(); + + const { t } = useTranslate('setting'); + const options = useMemo( + () => BedrockRegionList.map((x) => ({ value: x, label: t(x) })), + [t], + ); + + const handleOk = async () => { + const values = await form.validateFields(); + + const data = { + ...values, + llm_factory: llmFactory, + }; + + onOk?.(data); + }; + + return ( + { + return ( + + + {t('ollamaLink', { name: llmFactory })} + + {originNode} + + ); + }} + > +
+ + label={t('modelType')} + name="model_type" + initialValue={'chat'} + rules={[{ required: true, message: t('modelTypeMessage') }]} + > + + + + label={t('modelName')} + name="llm_name" + rules={[{ required: true, message: t('bedrockModelNameMessage') }]} + > + + + + label={t('addBedrockEngineAK')} + name="bedrock_ak" + rules={[{ required: true, message: t('bedrockAKMessage') }]} + > + + + + label={t('addBedrockSK')} + name="bedrock_sk" + rules={[{ required: true, message: t('bedrockSKMessage') }]} + > + + + + label={t('bedrockRegion')} + name="bedrock_region" + rules={[{ required: true, message: t('bedrockRegionMessage') }]} + > + + + +
+ ); +}; + +export default BedrockModal; diff --git a/web/src/pages/user-setting/setting-model/constant.ts b/web/src/pages/user-setting/setting-model/constant.ts new file mode 100644 index 000000000..3923c752b --- /dev/null +++ b/web/src/pages/user-setting/setting-model/constant.ts @@ -0,0 +1,33 @@ +// Please lowercase the file name +export const IconMap = { + 'Tongyi-Qianwen': 'tongyi', + Moonshot: 'moonshot', + OpenAI: 'openai', + 'ZHIPU-AI': 'zhipu', + 文心一言: 'wenxin', + Ollama: 'ollama', + Xinference: 'xinference', + DeepSeek: 'deepseek', + VolcEngine: 'volc_engine', + BaiChuan: 'baichuan', + Jina: 'jina', + MiniMax: 'chat-minimax', + Mistral: 'mistral', + 'Azure-OpenAI': 'azure', + Bedrock: 'bedrock', + Gemini: 'gemini', + Groq: 'groq-next', + OpenRouter: 'open-router', + LocalAI: 'local-ai', + StepFun: 'stepfun', +}; + +export const BedrockRegionList = [ + 'us-east-1', + 'us-west-2', + 'ap-southeast-1', + 'ap-northeast-1', + 'eu-central-1', + 'us-gov-west-1', + 'ap-southeast-2', +]; diff --git a/web/src/pages/user-setting/setting-model/hooks.ts b/web/src/pages/user-setting/setting-model/hooks.ts index 19ec98556..8550542b0 100644 --- a/web/src/pages/user-setting/setting-model/hooks.ts +++ b/web/src/pages/user-setting/setting-model/hooks.ts @@ -168,7 +168,6 @@ export const useSubmitOllama = () => { export const useSubmitVolcEngine = () => { const loading = useOneNamespaceEffectsLoading('settingModel', ['add_llm']); - const [selectedVolcFactory, setSelectedVolcFactory] = useState(''); const addLlm = useAddLlm(); const { visible: volcAddingVisible, @@ -186,18 +185,40 @@ export const useSubmitVolcEngine = () => { [hideVolcAddingModal, addLlm], ); - const handleShowVolcAddingModal = (llmFactory: string) => { - setSelectedVolcFactory(llmFactory); - showVolcAddingModal(); - }; - return { volcAddingLoading: loading, onVolcAddingOk, volcAddingVisible, hideVolcAddingModal, - showVolcAddingModal: handleShowVolcAddingModal, - selectedVolcFactory, + showVolcAddingModal, + }; +}; + +export const useSubmitBedrock = () => { + const loading = useOneNamespaceEffectsLoading('settingModel', ['add_llm']); + const addLlm = useAddLlm(); + const { + visible: bedrockAddingVisible, + hideModal: hideBedrockAddingModal, + showModal: showBedrockAddingModal, + } = useSetModalState(); + + const onBedrockAddingOk = useCallback( + async (payload: IAddLlmRequestBody) => { + const ret = await addLlm(payload); + if (ret === 0) { + hideBedrockAddingModal(); + } + }, + [hideBedrockAddingModal, addLlm], + ); + + return { + bedrockAddingLoading: loading, + onBedrockAddingOk, + bedrockAddingVisible, + hideBedrockAddingModal, + showBedrockAddingModal, }; }; diff --git a/web/src/pages/user-setting/setting-model/index.tsx b/web/src/pages/user-setting/setting-model/index.tsx index 677eb248e..3ce4e621d 100644 --- a/web/src/pages/user-setting/setting-model/index.tsx +++ b/web/src/pages/user-setting/setting-model/index.tsx @@ -28,14 +28,17 @@ import { Tooltip, Typography, } from 'antd'; -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import SettingTitle from '../components/setting-title'; import { isLocalLlmFactory } from '../utils'; import ApiKeyModal from './api-key-modal'; +import BedrockModal from './bedrock-modal'; +import { IconMap } from './constant'; import { useHandleDeleteLlm, useSelectModelProvidersLoading, useSubmitApiKey, + useSubmitBedrock, useSubmitOllama, useSubmitSystemModelSetting, useSubmitVolcEngine, @@ -43,31 +46,7 @@ import { import styles from './index.less'; import OllamaModal from './ollama-modal'; import SystemModelSettingModal from './system-model-setting-modal'; -import VolcEngineModal from './volcengine-model'; - -// Please lowercase the file name -const IconMap = { - 'Tongyi-Qianwen': 'tongyi', - Moonshot: 'moonshot', - OpenAI: 'openai', - 'ZHIPU-AI': 'zhipu', - 文心一言: 'wenxin', - Ollama: 'ollama', - Xinference: 'xinference', - DeepSeek: 'deepseek', - VolcEngine: 'volc_engine', - BaiChuan: 'baichuan', - Jina: 'jina', - MiniMax: 'chat-minimax', - Mistral: 'mistral', - 'Azure-OpenAI': 'azure', - Bedrock: 'bedrock', - Gemini: 'gemini', - Groq: 'groq-next', - OpenRouter: 'open-router', - LocalAI:'local-ai', - StepFun:'stepfun' -}; +import VolcEngineModal from './volcengine-modal'; const LlmIcon = ({ name }: { name: string }) => { const icon = IconMap[name as keyof typeof IconMap]; @@ -188,32 +167,37 @@ const UserSettingModel = () => { showVolcAddingModal, onVolcAddingOk, volcAddingLoading, - selectedVolcFactory, } = useSubmitVolcEngine(); - const handleApiKeyClick = useCallback( + const { + bedrockAddingLoading, + onBedrockAddingOk, + bedrockAddingVisible, + hideBedrockAddingModal, + showBedrockAddingModal, + } = useSubmitBedrock(); + + const ModalMap = useMemo( + () => ({ + Bedrock: showBedrockAddingModal, + VolcEngine: showVolcAddingModal, + }), + [showBedrockAddingModal, showVolcAddingModal], + ); + + const handleAddModel = useCallback( (llmFactory: string) => { if (isLocalLlmFactory(llmFactory)) { showLlmAddingModal(llmFactory); - } else if (llmFactory === 'VolcEngine') { - showVolcAddingModal('VolcEngine'); + } else if (llmFactory in ModalMap) { + ModalMap[llmFactory as keyof typeof ModalMap](); } else { showApiKeyModal({ llm_factory: llmFactory }); } }, - [showApiKeyModal, showLlmAddingModal, showVolcAddingModal], + [showApiKeyModal, showLlmAddingModal, ModalMap], ); - const handleAddModel = (llmFactory: string) => () => { - if (isLocalLlmFactory(llmFactory)) { - showLlmAddingModal(llmFactory); - } else if (llmFactory === 'VolcEngine') { - showVolcAddingModal('VolcEngine'); - } else { - handleApiKeyClick(llmFactory); - } - }; - const items: CollapseProps['items'] = [ { key: '1', @@ -223,7 +207,7 @@ const UserSettingModel = () => { grid={{ gutter: 16, column: 1 }} dataSource={llmList} renderItem={(item) => ( - + )} /> ), @@ -254,7 +238,7 @@ const UserSettingModel = () => { - @@ -305,8 +289,15 @@ const UserSettingModel = () => { hideModal={hideVolcAddingModal} onOk={onVolcAddingOk} loading={volcAddingLoading} - llmFactory={selectedVolcFactory} + llmFactory={'VolcEngine'} > + ); }; diff --git a/web/src/pages/user-setting/setting-model/volcengine-model/index.tsx b/web/src/pages/user-setting/setting-model/volcengine-modal/index.tsx similarity index 100% rename from web/src/pages/user-setting/setting-model/volcengine-model/index.tsx rename to web/src/pages/user-setting/setting-model/volcengine-modal/index.tsx