chore: support AWS Claude/Cloudflare/Coze

This commit is contained in:
MartialBE 2024-05-26 18:07:57 +08:00
parent ec9b6d1039
commit 2e7e563d75
No known key found for this signature in database
GPG Key ID: 27C0267EC84B0A5C
3 changed files with 220 additions and 145 deletions

View File

@ -11,12 +11,18 @@ export const CHANNEL_OPTIONS = {
value: 14,
color: 'primary'
},
// 33: {
// key: 33,
// text: 'AWS Claude',
// value: 33,
// color: 'primary'
// },
33: {
key: 33,
text: 'AWS Claude',
value: 33,
color: 'primary'
},
37: {
key: 37,
text: 'Cloudflare',
value: 37,
color: 'success'
},
3: {
key: 3,
text: 'Azure OpenAI',
@ -119,12 +125,12 @@ export const CHANNEL_OPTIONS = {
value: 32,
color: 'primary'
},
// 34: {
// key: 34,
// text: 'Coze',
// value: 34,
// color: 'primary'
// },
34: {
key: 34,
text: 'Coze',
value: 34,
color: 'primary'
},
35: {
key: 35,
text: 'Cohere',

View File

@ -40,8 +40,8 @@ const validationSchema = Yup.object().shape({
is_edit: Yup.boolean(),
name: Yup.string().required('名称 不能为空'),
type: Yup.number().required('渠道 不能为空'),
key: Yup.string().when('is_edit', {
is: false,
key: Yup.string().when(['is_edit', 'type'], {
is: (is_edit, type) => !is_edit && type !== 33,
then: Yup.string().required('密钥 不能为空')
}),
other: Yup.string(),
@ -107,6 +107,8 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
if (localModels.length > 0 && Array.isArray(values['models']) && values['models'].length == 0) {
setFieldValue('models', initialModel(localModels));
}
setFieldValue('config', {});
};
const fetchGroups = async () => {
@ -160,17 +162,25 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
if (values.type === 18 && values.other === '') {
values.other = 'v2.1';
}
if (values.key === '') {
if (values.config.ak !== '' && values.config.sk !== '' && values.config.region !== '') {
values.key = `${values.config.ak}|${values.config.sk}|${values.config.region}`;
}
}
let res;
const modelsStr = values.models.map((model) => model.id).join(',');
const configStr = JSON.stringify(values.config);
values.group = values.groups.join(',');
if (channelId) {
res = await API.put(`/api/channel/`, {
...values,
id: parseInt(channelId),
models: modelsStr
models: modelsStr,
config: configStr
});
} else {
res = await API.post(`/api/channel/`, { ...values, models: modelsStr });
res = await API.post(`/api/channel/`, { ...values, models: modelsStr, config: configStr });
}
const { success, message } = res.data;
if (success) {
@ -225,6 +235,10 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
if (data.model_mapping !== '') {
data.model_mapping = JSON.stringify(JSON.parse(data.model_mapping), null, 2);
}
if (data.config !== '') {
data.config = JSON.parse(data.config);
}
data.base_url = data.base_url ?? '';
data.is_edit = true;
initChannel(data.type);
@ -485,55 +499,78 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
</Button>
</ButtonGroup>
</Container>
<FormControl fullWidth error={Boolean(touched.key && errors.key)} sx={{ ...theme.typography.otherInput }}>
{!batchAdd ? (
<>
<InputLabel htmlFor="channel-key-label">{inputLabel.key}</InputLabel>
<OutlinedInput
id="channel-key-label"
label={inputLabel.key}
type="text"
value={values.key}
name="key"
onBlur={handleBlur}
onChange={handleChange}
inputProps={{}}
aria-describedby="helper-text-channel-key-label"
/>
</>
) : (
<TextField
multiline
id="channel-key-label"
label={inputLabel.key}
value={values.key}
name="key"
onBlur={handleBlur}
onChange={handleChange}
aria-describedby="helper-text-channel-key-label"
minRows={5}
placeholder={inputPrompt.key + ',一行一个密钥'}
/>
)}
{inputLabel.key && (
<>
<FormControl fullWidth error={Boolean(touched.key && errors.key)} sx={{ ...theme.typography.otherInput }}>
{!batchAdd ? (
<>
<InputLabel htmlFor="channel-key-label">{inputLabel.key}</InputLabel>
<OutlinedInput
id="channel-key-label"
label={inputLabel.key}
type="text"
value={values.key}
name="key"
onBlur={handleBlur}
onChange={handleChange}
inputProps={{}}
aria-describedby="helper-text-channel-key-label"
/>
</>
) : (
<TextField
multiline
id="channel-key-label"
label={inputLabel.key}
value={values.key}
name="key"
onBlur={handleBlur}
onChange={handleChange}
aria-describedby="helper-text-channel-key-label"
minRows={5}
placeholder={inputPrompt.key + ',一行一个密钥'}
/>
)}
{touched.key && errors.key ? (
<FormHelperText error id="helper-tex-channel-key-label">
{errors.key}
</FormHelperText>
) : (
<FormHelperText id="helper-tex-channel-key-label"> {inputPrompt.key} </FormHelperText>
)}
</FormControl>
{channelId === 0 && (
<Container
sx={{
textAlign: 'right'
}}
>
<Switch checked={batchAdd} onChange={(e) => setBatchAdd(e.target.checked)} />
批量添加
</Container>
{touched.key && errors.key ? (
<FormHelperText error id="helper-tex-channel-key-label">
{errors.key}
</FormHelperText>
) : (
<FormHelperText id="helper-tex-channel-key-label"> {inputPrompt.key} </FormHelperText>
)}
</FormControl>
{channelId === 0 && (
<Container
sx={{
textAlign: 'right'
}}
>
<Switch checked={batchAdd} onChange={(e) => setBatchAdd(e.target.checked)} />
批量添加
</Container>
)}
</>
)}
{inputLabel.config &&
Object.keys(inputLabel.config).map((configName) => {
return (
<FormControl key={'config.' + configName} fullWidth sx={{ ...theme.typography.otherInput }}>
<TextField
multiline
key={'config.' + configName}
name={'config.' + configName}
value={values.config?.[configName] || ''}
label={configName}
placeholder={inputPrompt.config[configName]}
onChange={handleChange}
/>
<FormHelperText id={`helper-tex-config.${configName}-label`}> {inputPrompt.config[configName]} </FormHelperText>
</FormControl>
);
})}
<FormControl fullWidth error={Boolean(touched.model_mapping && errors.model_mapping)} sx={{ ...theme.typography.otherInput }}>
{/* <InputLabel htmlFor="channel-model_mapping-label">{inputLabel.model_mapping}</InputLabel> */}
<TextField

View File

@ -1,177 +1,209 @@
const defaultConfig = {
input: {
name: "",
name: '',
type: 1,
key: "",
base_url: "",
other: "",
model_mapping: "",
key: '',
base_url: '',
other: '',
model_mapping: '',
models: [],
groups: ["default"],
groups: ['default'],
config: {}
},
inputLabel: {
name: "渠道名称",
type: "渠道类型",
base_url: "渠道API地址",
key: "密钥",
other: "其他参数",
models: "模型",
model_mapping: "模型映射关系",
groups: "用户组",
name: '渠道名称',
type: '渠道类型',
base_url: '渠道API地址',
key: '密钥',
other: '其他参数',
models: '模型',
model_mapping: '模型映射关系',
groups: '用户组',
config: null
},
prompt: {
type: "请选择渠道类型",
name: "请为渠道命名",
base_url: "可空请输入中转API地址例如通过cloudflare中转",
key: "请输入渠道对应的鉴权密钥",
other: "",
models: "请选择该渠道所支持的模型",
type: '请选择渠道类型',
name: '请为渠道命名',
base_url: '可空请输入中转API地址例如通过cloudflare中转',
key: '请输入渠道对应的鉴权密钥',
other: '',
models: '请选择该渠道所支持的模型',
model_mapping:
'请输入要修改的模型映射关系格式为api请求模型ID:实际转发给渠道的模型ID使用JSON数组表示例如{"gpt-3.5": "gpt-35"}',
groups: "请选择该渠道所支持的用户组",
groups: '请选择该渠道所支持的用户组',
config: null
},
modelGroup: "openai",
modelGroup: 'openai'
};
const typeConfig = {
3: {
inputLabel: {
base_url: "AZURE_OPENAI_ENDPOINT",
other: "默认 API 版本",
base_url: 'AZURE_OPENAI_ENDPOINT',
other: '默认 API 版本'
},
prompt: {
base_url: "请填写AZURE_OPENAI_ENDPOINT",
other: "请输入默认API版本例如2024-03-01-preview",
},
base_url: '请填写AZURE_OPENAI_ENDPOINT',
other: '请输入默认API版本例如2024-03-01-preview'
}
},
11: {
input: {
models: ["PaLM-2"],
models: ['PaLM-2']
},
modelGroup: "google palm",
modelGroup: 'google palm'
},
14: {
input: {
models: ["claude-instant-1", "claude-2", "claude-2.0", "claude-2.1"],
models: ['claude-instant-1', 'claude-2', 'claude-2.0', 'claude-2.1']
},
modelGroup: "anthropic",
modelGroup: 'anthropic'
},
15: {
input: {
models: ["ERNIE-Bot", "ERNIE-Bot-turbo", "ERNIE-Bot-4", "Embedding-V1"],
models: ['ERNIE-Bot', 'ERNIE-Bot-turbo', 'ERNIE-Bot-4', 'Embedding-V1']
},
prompt: {
key: "按照如下格式输入APIKey|SecretKey",
key: '按照如下格式输入APIKey|SecretKey'
},
modelGroup: "baidu",
modelGroup: 'baidu'
},
16: {
input: {
models: ["glm-4", "glm-4v", "glm-3-turbo", "chatglm_turbo", "chatglm_pro", "chatglm_std", "chatglm_lite"],
models: ['glm-4', 'glm-4v', 'glm-3-turbo', 'chatglm_turbo', 'chatglm_pro', 'chatglm_std', 'chatglm_lite']
},
modelGroup: "zhipu",
modelGroup: 'zhipu'
},
17: {
inputLabel: {
other: "插件参数",
other: '插件参数'
},
input: {
models: [
"qwen-turbo",
"qwen-plus",
"qwen-max",
"qwen-max-longcontext",
"text-embedding-v1",
],
models: ['qwen-turbo', 'qwen-plus', 'qwen-max', 'qwen-max-longcontext', 'text-embedding-v1']
},
prompt: {
other: "请输入插件参数,即 X-DashScope-Plugin 请求头的取值",
other: '请输入插件参数,即 X-DashScope-Plugin 请求头的取值'
},
modelGroup: "ali",
modelGroup: 'ali'
},
18: {
inputLabel: {
other: "版本号",
other: '版本号'
},
input: {
models: [
"SparkDesk",
'SparkDesk-v1.1',
'SparkDesk-v2.1',
'SparkDesk-v3.1',
'SparkDesk-v3.5'
],
models: ['SparkDesk', 'SparkDesk-v1.1', 'SparkDesk-v2.1', 'SparkDesk-v3.1', 'SparkDesk-v3.5']
},
prompt: {
key: "按照如下格式输入APPID|APISecret|APIKey",
other: "请输入版本号例如v3.1",
key: '按照如下格式输入APPID|APISecret|APIKey',
other: '请输入版本号例如v3.1'
},
modelGroup: "xunfei",
modelGroup: 'xunfei'
},
19: {
input: {
models: [
"360GPT_S2_V9",
"embedding-bert-512-v1",
"embedding_s1_v1",
"semantic_similarity_s1_v1",
],
models: ['360GPT_S2_V9', 'embedding-bert-512-v1', 'embedding_s1_v1', 'semantic_similarity_s1_v1']
},
modelGroup: "360",
modelGroup: '360'
},
22: {
prompt: {
key: "按照如下格式输入APIKey-AppId例如fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041",
},
key: '按照如下格式输入APIKey-AppId例如fastgpt-0sp2gtvfdgyi4k30jwlgwf1i-64f335d84283f05518e9e041'
}
},
23: {
input: {
models: ["hunyuan"],
models: ['hunyuan']
},
prompt: {
key: "按照如下格式输入AppId|SecretId|SecretKey",
key: '按照如下格式输入AppId|SecretId|SecretKey'
},
modelGroup: "tencent",
modelGroup: 'tencent'
},
24: {
inputLabel: {
other: "版本号",
other: '版本号'
},
input: {
models: ["gemini-pro"],
models: ['gemini-pro']
},
prompt: {
other: "请输入版本号例如v1",
other: '请输入版本号例如v1'
},
modelGroup: "google gemini",
modelGroup: 'google gemini'
},
25: {
input: {
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k']
},
modelGroup: "moonshot",
modelGroup: 'moonshot'
},
26: {
input: {
models: ['Baichuan2-Turbo', 'Baichuan2-Turbo-192k', 'Baichuan-Text-Embedding'],
models: ['Baichuan2-Turbo', 'Baichuan2-Turbo-192k', 'Baichuan-Text-Embedding']
},
modelGroup: "baichuan",
modelGroup: 'baichuan'
},
27: {
input: {
models: ['abab5.5s-chat', 'abab5.5-chat', 'abab6-chat'],
models: ['abab5.5s-chat', 'abab5.5-chat', 'abab6-chat']
},
modelGroup: "minimax",
modelGroup: 'minimax'
},
29: {
modelGroup: "groq",
modelGroup: 'groq'
},
30: {
modelGroup: "ollama",
modelGroup: 'ollama'
},
31: {
modelGroup: "lingyiwanwu",
modelGroup: 'lingyiwanwu'
},
33: {
inputLabel: {
key: '',
config: {
region: 'Region',
ak: 'Access Key',
sk: 'Secret Key'
}
},
prompt: {
key: '',
config: {
region: 'regione.g. us-west-2',
ak: 'AWS IAM Access Key',
sk: 'AWS IAM Secret Key'
}
},
modelGroup: 'anthropic'
},
37: {
inputLabel: {
config: {
user_id: 'Account ID'
}
},
prompt: {
config: {
user_id: '请输入 Account ID例如d8d7c61dbc334c32d3ced580e4bf42b4'
}
},
modelGroup: 'Cloudflare'
},
34: {
inputLabel: {
config: {
user_id: 'User ID'
}
},
prompt: {
models: '对于 Coze 而言,模型名称即 Bot ID你可以添加一个前缀 `bot-`,例如:`bot-123456`',
config: {
user_id: '生成该密钥的用户 ID'
}
},
modelGroup: 'Coze'
}
};
export { defaultConfig, typeConfig };