黄腾 aopstudio Kevin Hu commited on
Commit
6ec7653
·
1 Parent(s): ea25a77

add support for Tencent Cloud ASR (#2102)

Browse files

### What problem does this PR solve?

add support for Tencent Cloud ASR

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

---------

Co-authored-by: Zhedong Cen <[email protected]>
Co-authored-by: Kevin Hu <[email protected]>

api/apps/llm_app.py CHANGED
@@ -122,6 +122,10 @@ def add_llm():
122
  f'"hunyuan_sk": "{req.get("hunyuan_sk", "")}"' + '}'
123
  req["api_key"] = api_key
124
  return set_api_key()
 
 
 
 
125
  elif factory == "Bedrock":
126
  # For Bedrock, due to its special authentication method
127
  # Assemble bedrock_ak, bedrock_sk, bedrock_region
 
122
  f'"hunyuan_sk": "{req.get("hunyuan_sk", "")}"' + '}'
123
  req["api_key"] = api_key
124
  return set_api_key()
125
+ elif factory == "Tencent Cloud":
126
+ api_key = '{' + f'"tencent_cloud_sid": "{req.get("tencent_cloud_sid", "")}", ' \
127
+ f'"tencent_cloud_sk": "{req.get("tencent_cloud_sk", "")}"' + '}'
128
+ req["api_key"] = api_key
129
  elif factory == "Bedrock":
130
  # For Bedrock, due to its special authentication method
131
  # Assemble bedrock_ak, bedrock_sk, bedrock_region
conf/llm_factories.json CHANGED
@@ -3233,6 +3233,13 @@
3233
  "tags": "TTS",
3234
  "status": "1",
3235
  "llm": []
 
 
 
 
 
 
 
3236
  }
3237
  ]
3238
  }
 
3233
  "tags": "TTS",
3234
  "status": "1",
3235
  "llm": []
3236
+ },
3237
+ {
3238
+ "name": "Tencent Cloud",
3239
+ "logo": "",
3240
+ "tags": "SPEECH2TEXT",
3241
+ "status": "1",
3242
+ "llm": []
3243
  }
3244
  ]
3245
  }
rag/llm/__init__.py CHANGED
@@ -128,7 +128,8 @@ Seq2txtModel = {
128
  "Tongyi-Qianwen": QWenSeq2txt,
129
  "Ollama": OllamaSeq2txt,
130
  "Azure-OpenAI": AzureSeq2txt,
131
- "Xinference": XinferenceSeq2txt
 
132
  }
133
 
134
  TTSModel = {
 
128
  "Tongyi-Qianwen": QWenSeq2txt,
129
  "Ollama": OllamaSeq2txt,
130
  "Azure-OpenAI": AzureSeq2txt,
131
+ "Xinference": XinferenceSeq2txt,
132
+ "Tencent Cloud": TencentCloudSeq2txt
133
  }
134
 
135
  TTSModel = {
rag/llm/sequence2txt_model.py CHANGED
@@ -22,7 +22,8 @@ from openai import OpenAI
22
  import os
23
  import json
24
  from rag.utils import num_tokens_from_string
25
-
 
26
 
27
  class Base(ABC):
28
  def __init__(self, key, model_name):
@@ -35,6 +36,13 @@ class Base(ABC):
35
  response_format="text"
36
  )
37
  return transcription.text.strip(), num_tokens_from_string(transcription.text.strip())
 
 
 
 
 
 
 
38
 
39
 
40
  class GPTSeq2txt(Base):
@@ -87,3 +95,66 @@ class XinferenceSeq2txt(Base):
87
  def __init__(self, key, model_name="", base_url=""):
88
  self.client = OpenAI(api_key="xxx", base_url=base_url)
89
  self.model_name = model_name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  import os
23
  import json
24
  from rag.utils import num_tokens_from_string
25
+ import base64
26
+ import re
27
 
28
  class Base(ABC):
29
  def __init__(self, key, model_name):
 
36
  response_format="text"
37
  )
38
  return transcription.text.strip(), num_tokens_from_string(transcription.text.strip())
39
+
40
+ def audio2base64(self,audio):
41
+ if isinstance(audio, bytes):
42
+ return base64.b64encode(audio).decode("utf-8")
43
+ if isinstance(audio, io.BytesIO):
44
+ return base64.b64encode(audio.getvalue()).decode("utf-8")
45
+ raise TypeError("The input audio file should be in binary format.")
46
 
47
 
48
  class GPTSeq2txt(Base):
 
95
  def __init__(self, key, model_name="", base_url=""):
96
  self.client = OpenAI(api_key="xxx", base_url=base_url)
97
  self.model_name = model_name
98
+
99
+
100
+ class TencentCloudSeq2txt(Base):
101
+ def __init__(
102
+ self, key, model_name="16k_zh", base_url="https://asr.tencentcloudapi.com"
103
+ ):
104
+ from tencentcloud.common import credential
105
+ from tencentcloud.asr.v20190614 import asr_client
106
+
107
+ key = json.loads(key)
108
+ sid = key.get("tencent_cloud_sid", "")
109
+ sk = key.get("tencent_cloud_sk", "")
110
+ cred = credential.Credential(sid, sk)
111
+ self.client = asr_client.AsrClient(cred, "")
112
+ self.model_name = model_name
113
+
114
+ def transcription(self, audio, max_retries=60, retry_interval=5):
115
+ from tencentcloud.common.exception.tencent_cloud_sdk_exception import (
116
+ TencentCloudSDKException,
117
+ )
118
+ from tencentcloud.asr.v20190614 import models
119
+ import time
120
+
121
+ b64 = self.audio2base64(audio)
122
+ try:
123
+ # dispatch disk
124
+ req = models.CreateRecTaskRequest()
125
+ params = {
126
+ "EngineModelType": self.model_name,
127
+ "ChannelNum": 1,
128
+ "ResTextFormat": 0,
129
+ "SourceType": 1,
130
+ "Data": b64,
131
+ }
132
+ req.from_json_string(json.dumps(params))
133
+ resp = self.client.CreateRecTask(req)
134
+
135
+ # loop query
136
+ req = models.DescribeTaskStatusRequest()
137
+ params = {"TaskId": resp.Data.TaskId}
138
+ req.from_json_string(json.dumps(params))
139
+ retries = 0
140
+ while retries < max_retries:
141
+ resp = self.client.DescribeTaskStatus(req)
142
+ if resp.Data.StatusStr == "success":
143
+ text = re.sub(
144
+ r"\[\d+:\d+\.\d+,\d+:\d+\.\d+\]\s*", "", resp.Data.Result
145
+ ).strip()
146
+ return text, num_tokens_from_string(text)
147
+ elif resp.Data.StatusStr == "failed":
148
+ return (
149
+ "**ERROR**: Failed to retrieve speech recognition results.",
150
+ 0,
151
+ )
152
+ else:
153
+ time.sleep(retry_interval)
154
+ retries += 1
155
+ return "**ERROR**: Max retries exceeded. Task may still be processing.", 0
156
+
157
+ except TencentCloudSDKException as e:
158
+ return "**ERROR**: " + str(e), 0
159
+ except Exception as e:
160
+ return "**ERROR**: " + str(e), 0
web/src/assets/svg/llm/tencent-cloud.svg ADDED
web/src/locales/en.ts CHANGED
@@ -506,6 +506,7 @@ The above is the content you need to summarize.`,
506
  vision: 'Does it support Vision?',
507
  ollamaLink: 'How to integrate {{name}}',
508
  FishAudioLink: 'How to use FishAudio',
 
509
  volcModelNameMessage: 'Please input your model name!',
510
  addEndpointID: 'EndpointID of the model',
511
  endpointIDMessage: 'Please input your EndpointID of the model',
@@ -529,6 +530,10 @@ The above is the content you need to summarize.`,
529
  HunyuanSIDMessage: 'Please input your Secret ID',
530
  addHunyuanSK: 'Hunyuan Secret Key',
531
  HunyuanSKMessage: 'Please input your Secret Key',
 
 
 
 
532
  SparkModelNameMessage: 'Please select Spark model',
533
  addSparkAPIPassword: 'Spark APIPassword',
534
  SparkAPIPasswordMessage: 'please input your APIPassword',
 
506
  vision: 'Does it support Vision?',
507
  ollamaLink: 'How to integrate {{name}}',
508
  FishAudioLink: 'How to use FishAudio',
509
+ TencentCloudLink: 'How to use TencentCloud ASR',
510
  volcModelNameMessage: 'Please input your model name!',
511
  addEndpointID: 'EndpointID of the model',
512
  endpointIDMessage: 'Please input your EndpointID of the model',
 
530
  HunyuanSIDMessage: 'Please input your Secret ID',
531
  addHunyuanSK: 'Hunyuan Secret Key',
532
  HunyuanSKMessage: 'Please input your Secret Key',
533
+ addTencentCloudSID: 'TencentCloud Secret ID',
534
+ TencentCloudSIDMessage: 'Please input your Secret ID',
535
+ addTencentCloudSK: 'TencentCloud Secret Key',
536
+ TencentCloudSKMessage: 'Please input your Secret Key',
537
  SparkModelNameMessage: 'Please select Spark model',
538
  addSparkAPIPassword: 'Spark APIPassword',
539
  SparkAPIPasswordMessage: 'please input your APIPassword',
web/src/locales/zh-traditional.ts CHANGED
@@ -468,6 +468,7 @@ export default {
468
  baseUrlNameMessage: '請輸入基礎 Url!',
469
  ollamaLink: '如何集成 {{name}}',
470
  FishAudioLink: '如何使用Fish Audio',
 
471
  volcModelNameMessage: '請輸入模型名稱!',
472
  addEndpointID: '模型 EndpointID',
473
  endpointIDMessage: '請輸入模型對應的EndpointID',
@@ -491,6 +492,10 @@ export default {
491
  HunyuanSIDMessage: '請輸入 Secret ID',
492
  addHunyuanSK: '混元 Secret Key',
493
  HunyuanSKMessage: '請輸入 Secret Key',
 
 
 
 
494
  SparkModelNameMessage: '請選擇星火模型!',
495
  addSparkAPIPassword: '星火 APIPassword',
496
  SparkAPIPasswordMessage: '請輸入 APIPassword',
 
468
  baseUrlNameMessage: '請輸入基礎 Url!',
469
  ollamaLink: '如何集成 {{name}}',
470
  FishAudioLink: '如何使用Fish Audio',
471
+ TencentCloudLink: '如何使用騰訊雲語音識別',
472
  volcModelNameMessage: '請輸入模型名稱!',
473
  addEndpointID: '模型 EndpointID',
474
  endpointIDMessage: '請輸入模型對應的EndpointID',
 
492
  HunyuanSIDMessage: '請輸入 Secret ID',
493
  addHunyuanSK: '混元 Secret Key',
494
  HunyuanSKMessage: '請輸入 Secret Key',
495
+ addTencentCloudSID: '騰訊雲 Secret ID',
496
+ TencentCloudSIDMessage: '請輸入 Secret ID',
497
+ addTencentCloudSK: '騰訊雲 Secret Key',
498
+ TencentCloudSKMessage: '請輸入 Secret Key',
499
  SparkModelNameMessage: '請選擇星火模型!',
500
  addSparkAPIPassword: '星火 APIPassword',
501
  SparkAPIPasswordMessage: '請輸入 APIPassword',
web/src/locales/zh.ts CHANGED
@@ -485,6 +485,7 @@ export default {
485
  baseUrlNameMessage: '请输入基础 Url!',
486
  ollamaLink: '如何集成 {{name}}',
487
  FishAudioLink: '如何使用Fish Audio',
 
488
  volcModelNameMessage: '请输入模型名称!',
489
  addEndpointID: '模型 EndpointID',
490
  endpointIDMessage: '请输入模型对应的EndpointID',
@@ -508,6 +509,10 @@ export default {
508
  HunyuanSIDMessage: '请输入 Secret ID',
509
  addHunyuanSK: '混元 Secret Key',
510
  HunyuanSKMessage: '请输入 Secret Key',
 
 
 
 
511
  SparkModelNameMessage: '请选择星火模型!',
512
  addSparkAPIPassword: '星火 APIPassword',
513
  SparkAPIPasswordMessage: '请输入 APIPassword',
 
485
  baseUrlNameMessage: '请输入基础 Url!',
486
  ollamaLink: '如何集成 {{name}}',
487
  FishAudioLink: '如何使用Fish Audio',
488
+ TencentCloudLink: '如何使用腾讯云语音识别',
489
  volcModelNameMessage: '请输入模型名称!',
490
  addEndpointID: '模型 EndpointID',
491
  endpointIDMessage: '请输入模型对应的EndpointID',
 
509
  HunyuanSIDMessage: '请输入 Secret ID',
510
  addHunyuanSK: '混元 Secret Key',
511
  HunyuanSKMessage: '请输入 Secret Key',
512
+ addTencentCloudSID: '腾讯云 Secret ID',
513
+ TencentCloudSIDMessage: '请输入 Secret ID',
514
+ addTencentCloudSK: '腾讯云 Secret Key',
515
+ TencentCloudSKMessage: '请输入 Secret Key',
516
  SparkModelNameMessage: '请选择星火模型!',
517
  addSparkAPIPassword: '星火 APIPassword',
518
  SparkAPIPasswordMessage: '请输入 APIPassword',
web/src/pages/user-setting/setting-model/Tencent-modal/index.tsx ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useTranslate } from '@/hooks/common-hooks';
2
+ import { IModalProps } from '@/interfaces/common';
3
+ import { IAddLlmRequestBody } from '@/interfaces/request/llm';
4
+ import { Flex, Form, Input, Modal, Select, Space } from 'antd';
5
+ import omit from 'lodash/omit';
6
+
7
+ type FieldType = IAddLlmRequestBody & {
8
+ TencentCloud_sid: string;
9
+ TencentCloud_sk: string;
10
+ };
11
+
12
+ const { Option } = Select;
13
+
14
+ const TencentCloudModal = ({
15
+ visible,
16
+ hideModal,
17
+ onOk,
18
+ loading,
19
+ llmFactory,
20
+ }: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
21
+ const [form] = Form.useForm<FieldType>();
22
+
23
+ const { t } = useTranslate('setting');
24
+
25
+ const handleOk = async () => {
26
+ const values = await form.validateFields();
27
+ const modelType = values.model_type;
28
+
29
+ const data = {
30
+ ...omit(values),
31
+ model_type: modelType,
32
+ llm_factory: llmFactory,
33
+ };
34
+ console.info(data);
35
+
36
+ onOk?.(data);
37
+ };
38
+
39
+ return (
40
+ <Modal
41
+ title={t('addLlmTitle', { name: llmFactory })}
42
+ open={visible}
43
+ onOk={handleOk}
44
+ onCancel={hideModal}
45
+ okButtonProps={{ loading }}
46
+ footer={(originNode: React.ReactNode) => {
47
+ return (
48
+ <Flex justify={'space-between'}>
49
+ <a
50
+ href={`https://cloud.tencent.com/document/api/1093/37823`}
51
+ target="_blank"
52
+ rel="noreferrer"
53
+ >
54
+ {t('TencentCloudLink')}
55
+ </a>
56
+ <Space>{originNode}</Space>
57
+ </Flex>
58
+ );
59
+ }}
60
+ confirmLoading={loading}
61
+ >
62
+ <Form
63
+ name="basic"
64
+ style={{ maxWidth: 600 }}
65
+ autoComplete="off"
66
+ layout={'vertical'}
67
+ form={form}
68
+ >
69
+ <Form.Item<FieldType>
70
+ label={t('modelType')}
71
+ name="model_type"
72
+ initialValue={'speech2text'}
73
+ rules={[{ required: true, message: t('modelTypeMessage') }]}
74
+ >
75
+ <Select placeholder={t('modelTypeMessage')}>
76
+ <Option value="speech2text">speech2text</Option>
77
+ </Select>
78
+ </Form.Item>
79
+ <Form.Item<FieldType>
80
+ label={t('modelName')}
81
+ name="llm_name"
82
+ initialValue={'16k_zh'}
83
+ rules={[{ required: true, message: t('SparkModelNameMessage') }]}
84
+ >
85
+ <Select placeholder={t('modelTypeMessage')}>
86
+ <Option value="16k_zh">16k_zh</Option>
87
+ <Option value="16k_zh_large">16k_zh_large</Option>
88
+ <Option value="16k_multi_lang">16k_multi_lang</Option>
89
+ <Option value="16k_zh_dialect">16k_zh_dialect</Option>
90
+ <Option value="16k_en">16k_en</Option>
91
+ <Option value="16k_yue">16k_yue</Option>
92
+ <Option value="16k_zh-PY">16k_zh-PY</Option>
93
+ <Option value="16k_ja">16k_ja</Option>
94
+ <Option value="16k_ko">16k_ko</Option>
95
+ <Option value="16k_vi">16k_vi</Option>
96
+ <Option value="16k_ms">16k_ms</Option>
97
+ <Option value="16k_id">16k_id</Option>
98
+ <Option value="16k_fil">16k_fil</Option>
99
+ <Option value="16k_th">16k_th</Option>
100
+ <Option value="16k_pt">16k_pt</Option>
101
+ <Option value="16k_tr">16k_tr</Option>
102
+ <Option value="16k_ar">16k_ar</Option>
103
+ <Option value="16k_es">16k_es</Option>
104
+ <Option value="16k_hi">16k_hi</Option>
105
+ <Option value="16k_fr">16k_fr</Option>
106
+ <Option value="16k_zh_medical">16k_zh_medical</Option>
107
+ <Option value="16k_de">16k_de</Option>
108
+ </Select>
109
+ </Form.Item>
110
+ <Form.Item<FieldType>
111
+ label={t('addTencentCloudSID')}
112
+ name="TencentCloud_sid"
113
+ rules={[{ required: true, message: t('TencentCloudSIDMessage') }]}
114
+ >
115
+ <Input placeholder={t('TencentCloudSIDMessage')} />
116
+ </Form.Item>
117
+ <Form.Item<FieldType>
118
+ label={t('addTencentCloudSK')}
119
+ name="TencentCloud_sk"
120
+ rules={[{ required: true, message: t('TencentCloudSKMessage') }]}
121
+ >
122
+ <Input placeholder={t('TencentCloudSKMessage')} />
123
+ </Form.Item>
124
+ </Form>
125
+ </Modal>
126
+ );
127
+ };
128
+
129
+ export default TencentCloudModal;
web/src/pages/user-setting/setting-model/constant.ts CHANGED
@@ -36,6 +36,7 @@ export const IconMap = {
36
  'XunFei Spark': 'spark',
37
  BaiduYiyan: 'yiyan',
38
  'Fish Audio': 'fish-audio',
 
39
  };
40
 
41
  export const BedrockRegionList = [
 
36
  'XunFei Spark': 'spark',
37
  BaiduYiyan: 'yiyan',
38
  'Fish Audio': 'fish-audio',
39
+ 'Tencent Cloud': 'tencent-cloud',
40
  };
41
 
42
  export const BedrockRegionList = [
web/src/pages/user-setting/setting-model/fish-audio-modal/index.tsx CHANGED
@@ -81,14 +81,14 @@ const FishAudioModal = ({
81
  </Form.Item>
82
  <Form.Item<FieldType>
83
  label={t('addFishAudioAK')}
84
- name="FishAudio_ak"
85
  rules={[{ required: true, message: t('FishAudioAKMessage') }]}
86
  >
87
  <Input placeholder={t('FishAudioAKMessage')} />
88
  </Form.Item>
89
  <Form.Item<FieldType>
90
  label={t('addFishAudioRefID')}
91
- name="FishAudio_refid"
92
  rules={[{ required: false, message: t('FishAudioRefIDMessage') }]}
93
  >
94
  <Input placeholder={t('FishAudioRefIDMessage')} />
 
81
  </Form.Item>
82
  <Form.Item<FieldType>
83
  label={t('addFishAudioAK')}
84
+ name="fish_audio_ak"
85
  rules={[{ required: true, message: t('FishAudioAKMessage') }]}
86
  >
87
  <Input placeholder={t('FishAudioAKMessage')} />
88
  </Form.Item>
89
  <Form.Item<FieldType>
90
  label={t('addFishAudioRefID')}
91
+ name="fish_audio_refid"
92
  rules={[{ required: false, message: t('FishAudioRefIDMessage') }]}
93
  >
94
  <Input placeholder={t('FishAudioRefIDMessage')} />
web/src/pages/user-setting/setting-model/hooks.ts CHANGED
@@ -190,6 +190,33 @@ export const useSubmitHunyuan = () => {
190
  };
191
  };
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  export const useSubmitSpark = () => {
194
  const { addLlm, loading } = useAddLlm();
195
  const {
 
190
  };
191
  };
192
 
193
+ export const useSubmitTencentCloud = () => {
194
+ const { addLlm, loading } = useAddLlm();
195
+ const {
196
+ visible: TencentCloudAddingVisible,
197
+ hideModal: hideTencentCloudAddingModal,
198
+ showModal: showTencentCloudAddingModal,
199
+ } = useSetModalState();
200
+
201
+ const onTencentCloudAddingOk = useCallback(
202
+ async (payload: IAddLlmRequestBody) => {
203
+ const ret = await addLlm(payload);
204
+ if (ret === 0) {
205
+ hideTencentCloudAddingModal();
206
+ }
207
+ },
208
+ [hideTencentCloudAddingModal, addLlm],
209
+ );
210
+
211
+ return {
212
+ TencentCloudAddingLoading: loading,
213
+ onTencentCloudAddingOk,
214
+ TencentCloudAddingVisible,
215
+ hideTencentCloudAddingModal,
216
+ showTencentCloudAddingModal,
217
+ };
218
+ };
219
+
220
  export const useSubmitSpark = () => {
221
  const { addLlm, loading } = useAddLlm();
222
  const {
web/src/pages/user-setting/setting-model/index.tsx CHANGED
@@ -27,6 +27,7 @@ import {
27
  import { useCallback, useMemo } from 'react';
28
  import SettingTitle from '../components/setting-title';
29
  import { isLocalLlmFactory } from '../utils';
 
30
  import ApiKeyModal from './api-key-modal';
31
  import BedrockModal from './bedrock-modal';
32
  import { IconMap } from './constant';
@@ -40,6 +41,7 @@ import {
40
  useSubmitOllama,
41
  useSubmitSpark,
42
  useSubmitSystemModelSetting,
 
43
  useSubmitVolcEngine,
44
  useSubmityiyan,
45
  } from './hooks';
@@ -101,7 +103,8 @@ const ModelCard = ({ item, clickApiKey }: IModelCardProps) => {
101
  item.name === 'Tencent Hunyuan' ||
102
  item.name === 'XunFei Spark' ||
103
  item.name === 'BaiduYiyan' ||
104
- item.name === 'Fish Audio'
 
105
  ? t('addTheModel')
106
  : 'API-Key'}
107
  <SettingOutlined />
@@ -183,6 +186,14 @@ const UserSettingModel = () => {
183
  HunyuanAddingLoading,
184
  } = useSubmitHunyuan();
185
 
 
 
 
 
 
 
 
 
186
  const {
187
  SparkAddingVisible,
188
  hideSparkAddingModal,
@@ -223,11 +234,13 @@ const UserSettingModel = () => {
223
  'XunFei Spark': showSparkAddingModal,
224
  BaiduYiyan: showyiyanAddingModal,
225
  'Fish Audio': showFishAudioAddingModal,
 
226
  }),
227
  [
228
  showBedrockAddingModal,
229
  showVolcAddingModal,
230
  showHunyuanAddingModal,
 
231
  showSparkAddingModal,
232
  showyiyanAddingModal,
233
  showFishAudioAddingModal,
@@ -349,6 +362,13 @@ const UserSettingModel = () => {
349
  loading={HunyuanAddingLoading}
350
  llmFactory={'Tencent Hunyuan'}
351
  ></HunyuanModal>
 
 
 
 
 
 
 
352
  <SparkModal
353
  visible={SparkAddingVisible}
354
  hideModal={hideSparkAddingModal}
 
27
  import { useCallback, useMemo } from 'react';
28
  import SettingTitle from '../components/setting-title';
29
  import { isLocalLlmFactory } from '../utils';
30
+ import TencentCloudModal from './Tencent-modal';
31
  import ApiKeyModal from './api-key-modal';
32
  import BedrockModal from './bedrock-modal';
33
  import { IconMap } from './constant';
 
41
  useSubmitOllama,
42
  useSubmitSpark,
43
  useSubmitSystemModelSetting,
44
+ useSubmitTencentCloud,
45
  useSubmitVolcEngine,
46
  useSubmityiyan,
47
  } from './hooks';
 
103
  item.name === 'Tencent Hunyuan' ||
104
  item.name === 'XunFei Spark' ||
105
  item.name === 'BaiduYiyan' ||
106
+ item.name === 'Fish Audio' ||
107
+ item.name === 'Tencent Cloud'
108
  ? t('addTheModel')
109
  : 'API-Key'}
110
  <SettingOutlined />
 
186
  HunyuanAddingLoading,
187
  } = useSubmitHunyuan();
188
 
189
+ const {
190
+ TencentCloudAddingVisible,
191
+ hideTencentCloudAddingModal,
192
+ showTencentCloudAddingModal,
193
+ onTencentCloudAddingOk,
194
+ TencentCloudAddingLoading,
195
+ } = useSubmitTencentCloud();
196
+
197
  const {
198
  SparkAddingVisible,
199
  hideSparkAddingModal,
 
234
  'XunFei Spark': showSparkAddingModal,
235
  BaiduYiyan: showyiyanAddingModal,
236
  'Fish Audio': showFishAudioAddingModal,
237
+ 'Tencent Cloud': showTencentCloudAddingModal,
238
  }),
239
  [
240
  showBedrockAddingModal,
241
  showVolcAddingModal,
242
  showHunyuanAddingModal,
243
+ showTencentCloudAddingModal,
244
  showSparkAddingModal,
245
  showyiyanAddingModal,
246
  showFishAudioAddingModal,
 
362
  loading={HunyuanAddingLoading}
363
  llmFactory={'Tencent Hunyuan'}
364
  ></HunyuanModal>
365
+ <TencentCloudModal
366
+ visible={TencentCloudAddingVisible}
367
+ hideModal={hideTencentCloudAddingModal}
368
+ onOk={onTencentCloudAddingOk}
369
+ loading={TencentCloudAddingLoading}
370
+ llmFactory={'Tencent TencentCloud'}
371
+ ></TencentCloudModal>
372
  <SparkModal
373
  visible={SparkAddingVisible}
374
  hideModal={hideSparkAddingModal}