mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
Merge branch 'feature/1.6-cx' into 'main'
feat: feature/1.6-Integrate custom model See merge request apipark/APIPark!251
This commit is contained in:
@@ -897,5 +897,6 @@
|
||||
"K3d2324d0": "Deletion failed.",
|
||||
"Kce2fcdbf": "No Permission",
|
||||
"K24f6a5b4": "Custom (Empty Template)",
|
||||
"Kea608112": "Load Preset Template"
|
||||
"Kea608112": "Load Preset Template",
|
||||
"Kee7de862": "Edit Provider( (0) )"
|
||||
}
|
||||
|
||||
@@ -919,5 +919,6 @@
|
||||
"K3d2324d0": "削除に失敗しました。",
|
||||
"Kce2fcdbf": "権限がありません",
|
||||
"K24f6a5b4": "カスタム(空のテンプレート)",
|
||||
"Kea608112": "プリセットテンプレートを読み込む"
|
||||
"Kea608112": "プリセットテンプレートを読み込む",
|
||||
"Kee7de862": "サプライヤーを編集( (0) )"
|
||||
}
|
||||
|
||||
@@ -850,5 +850,6 @@
|
||||
"K3d2324d0": "删除失败",
|
||||
"Kce2fcdbf": "暂无权限",
|
||||
"K24f6a5b4": "自定义(空模板)",
|
||||
"Kea608112": "载入预置模板"
|
||||
"Kea608112": "载入预置模板",
|
||||
"Kee7de862": "编辑供应商( (0) )"
|
||||
}
|
||||
|
||||
@@ -919,5 +919,6 @@
|
||||
"K3d2324d0": "刪除失敗。",
|
||||
"Kce2fcdbf": "暫無權限",
|
||||
"K24f6a5b4": "自訂(空模板)",
|
||||
"Kea608112": "載入預設模板"
|
||||
"Kea608112": "載入預設模板",
|
||||
"Kee7de862": "編輯供應商( (0) )"
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
if ((setModelValue && providers.length) || defaultId) {
|
||||
const id = defaultId || providers[0].id
|
||||
form.setFieldValue('modelMode', id)
|
||||
getModelConfig(id)
|
||||
getModelConfig(id, defaultId)
|
||||
}
|
||||
} else {
|
||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||
@@ -128,7 +128,7 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
* 获取模型配置
|
||||
* @param id
|
||||
*/
|
||||
const getModelConfig = (id: string) => {
|
||||
const getModelConfig = (id: string, defaultId?: string | number) => {
|
||||
getLlmList(id)
|
||||
fetchData<BasicResponse<{ providers: ModelDetailData[] }>>(`ai/provider/config`, {
|
||||
method: 'GET',
|
||||
@@ -139,7 +139,8 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
const { code, data, msg } = response
|
||||
if (code === STATUS_CODE.SUCCESS) {
|
||||
const modelEntity = {
|
||||
...data.provider
|
||||
...data.provider,
|
||||
isNewProvider: !!defaultId
|
||||
}
|
||||
setLocalEntity(modelEntity)
|
||||
setFormFieldsValue(modelEntity)
|
||||
@@ -267,12 +268,19 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
* 添加模型
|
||||
*/
|
||||
const addModel = () => {
|
||||
const providerName = form.getFieldValue('modelMode') || localEntity?.name
|
||||
const providerName = localEntity?.name || form.getFieldValue('modelMode')
|
||||
const showAccessConfig = localEntity?.model_config?.access_configuration_status || false
|
||||
const accessConfig = localEntity?.model_config?.access_configuration_demo || ''
|
||||
modal.confirm({
|
||||
title: $t('添加 (0) 模型', [providerName]),
|
||||
content: <AddModels ref={addModelModalRef} showAccessConfig={showAccessConfig} accessConfig={accessConfig} providerID={localEntity?.id}></AddModels>,
|
||||
content: (
|
||||
<AddModels
|
||||
ref={addModelModalRef}
|
||||
showAccessConfig={showAccessConfig}
|
||||
accessConfig={accessConfig}
|
||||
providerID={localEntity?.id}
|
||||
></AddModels>
|
||||
),
|
||||
onOk: () => {
|
||||
return addModelModalRef.current?.save().then((res) => {
|
||||
if (res === true) {
|
||||
@@ -298,7 +306,7 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
onOk: () => {
|
||||
return addProviderModalRef.current?.save().then((res) => {
|
||||
if (res) {
|
||||
getModelProviderList(false, res)
|
||||
getModelProviderList(false, res.id)
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -326,14 +334,16 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
autoComplete="off"
|
||||
disabled={readOnly}
|
||||
>
|
||||
{modelMode === 'manual' && (
|
||||
{modelMode === 'manual' && !localEntity?.isNewProvider && (
|
||||
<Form.Item<ModelDetailData> label={$t('模型供应商')}>
|
||||
<span className="absolute top-[-28px] right-0 text-theme cursor-pointer" onClick={addProvider}>
|
||||
+ {$t('添加自定义供应商')}
|
||||
</span>
|
||||
<Form.Item<ModelDetailData> name="modelMode" rules={[{ required: true }]}>
|
||||
<Select
|
||||
showSearch
|
||||
className="w-INPUT_NORMAL"
|
||||
filterOption={(input, option) => (option?.searchText ?? '').includes(input.toLowerCase())}
|
||||
placeholder={$t(PLACEHOLDER.select)}
|
||||
loading={modelModeLoading}
|
||||
options={modelProviderListRef.current?.map((x) => ({
|
||||
@@ -342,7 +352,8 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
<div className="flex items-center gap-[10px]">
|
||||
<span>{x.name}</span>
|
||||
</div>
|
||||
)
|
||||
),
|
||||
searchText: x.name.toLowerCase()
|
||||
}))}
|
||||
onChange={(e) => {
|
||||
getModelConfig(e)
|
||||
@@ -355,22 +366,25 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle, AiSettingM
|
||||
<span className="absolute top-[-28px] right-0 text-theme cursor-pointer" onClick={addModel}>
|
||||
+ {$t('添加模型')}
|
||||
</span>
|
||||
<Form.Item<ModelDetailData> name="defaultLlm" rules={[{ required: true }]}>
|
||||
<Select
|
||||
className="w-INPUT_NORMAL"
|
||||
placeholder={$t(PLACEHOLDER.select)}
|
||||
loading={loading}
|
||||
options={llmList?.map((x) => ({
|
||||
value: x.id,
|
||||
label: (
|
||||
<div className="flex items-center gap-[10px]">
|
||||
<span>{x.name || x.id}</span>
|
||||
{x?.scopes?.map((s) => <Tag key={s}>{s?.toLocaleUpperCase()}</Tag>)}
|
||||
</div>
|
||||
)
|
||||
}))}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
<Form.Item<ModelDetailData> name="defaultLlm" rules={[{ required: true }]}>
|
||||
<Select
|
||||
showSearch
|
||||
className="w-INPUT_NORMAL"
|
||||
filterOption={(input, option) => (option?.searchText ?? '').includes(input.toLowerCase())}
|
||||
placeholder={$t(PLACEHOLDER.select)}
|
||||
loading={loading}
|
||||
options={llmList?.map((x) => ({
|
||||
value: x.id,
|
||||
label: (
|
||||
<div className="flex items-center gap-[10px]">
|
||||
<span>{x.name || x.id}</span>
|
||||
{x?.scopes?.map((s) => <Tag key={s}>{s?.toLocaleUpperCase()}</Tag>)}
|
||||
</div>
|
||||
),
|
||||
searchText: x.name.toLowerCase()
|
||||
}))}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
{source === 'guide' && (
|
||||
<Form.Item label={$t('所属团队')} name="team" className="mt-[16px]" rules={[{ required: true }]}>
|
||||
|
||||
@@ -28,7 +28,7 @@ const OnlineModelList: React.FC = () => {
|
||||
const [modalVisible, setModalVisible] = useState(false)
|
||||
const [selectedProviderID, setSelectedProviderID] = useState('')
|
||||
const [selectedProviderName, setSelectedProviderName] = useState('')
|
||||
const [showDrawerFooterLeft, setShowDrawerFooterLeft] = useState(false)
|
||||
const [currentEditDrawerData, setCurrentEditDrawerData] = useState<any>()
|
||||
|
||||
const handleEdit = (record: ModelListData) => {
|
||||
setEntity({
|
||||
@@ -117,7 +117,7 @@ const OnlineModelList: React.FC = () => {
|
||||
// 更新抽屉底部
|
||||
const updateEntityData = (data: any) => {
|
||||
// 0 常规,1 自定义
|
||||
setShowDrawerFooterLeft(!data.type)
|
||||
setCurrentEditDrawerData(data)
|
||||
setFooterLeft(
|
||||
<a target="_blank" rel="noopener noreferrer" href={data?.getApikeyUrl} className="flex items-center gap-[8px]">
|
||||
<span>{$t('从 (0) 获取 API KEY', [data?.name])}</span>
|
||||
@@ -269,7 +269,7 @@ const OnlineModelList: React.FC = () => {
|
||||
onAddNewBtnClick={() => setDrawerOpen(true)}
|
||||
/>
|
||||
<DrawerWithFooter
|
||||
title={entity ? $t('编辑供应商') : $t('添加供应商')}
|
||||
title={currentEditDrawerData?.isNewProvider ? $t('编辑供应商( (0) )', [currentEditDrawerData.name]) : entity ? $t('编辑供应商') : $t('添加供应商')}
|
||||
open={drawerOpen}
|
||||
width="30%"
|
||||
onClose={() => {
|
||||
@@ -284,7 +284,7 @@ const OnlineModelList: React.FC = () => {
|
||||
return res
|
||||
})
|
||||
}
|
||||
footerLeft={showDrawerFooterLeft ? footerLeft : undefined}
|
||||
footerLeft={!currentEditDrawerData?.type ? footerLeft : undefined}
|
||||
submitAccess=""
|
||||
>
|
||||
<AiSettingModalContent
|
||||
|
||||
@@ -3,12 +3,13 @@ import { $t } from '@common/locales'
|
||||
import { BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE } from '@common/const/const'
|
||||
import { useFetch } from '@common/hooks/http'
|
||||
import { forwardRef, useImperativeHandle } from 'react'
|
||||
import { AISettingEntityItem } from '../types'
|
||||
type modelFieldType = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export type addProviderContentHandle = {
|
||||
save: () => Promise<number | string>
|
||||
save: () => Promise<AISettingEntityItem>
|
||||
}
|
||||
|
||||
type addProviderContentProps = {
|
||||
@@ -24,7 +25,7 @@ const AddProvider = forwardRef<addProviderContentHandle, addProviderContentProps
|
||||
* 保存
|
||||
* @returns
|
||||
*/
|
||||
const save: () => Promise<number | string> = () => {
|
||||
const save: () => Promise<AISettingEntityItem> = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
form
|
||||
@@ -41,7 +42,7 @@ const AddProvider = forwardRef<addProviderContentHandle, addProviderContentProps
|
||||
const { code, data, msg } = response
|
||||
if (code === STATUS_CODE.SUCCESS) {
|
||||
message.success($t(RESPONSE_TIPS.success) || msg)
|
||||
resolve(data.id)
|
||||
resolve(data.provider)
|
||||
} else {
|
||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||
reject(msg || $t(RESPONSE_TIPS.error))
|
||||
|
||||
@@ -37,6 +37,7 @@ export interface AISettingEntityItem {
|
||||
name?: string
|
||||
type?: number
|
||||
model_config?: ModelConfigItem
|
||||
isNewProvider?: boolean
|
||||
}
|
||||
export interface ModelDetailData extends ModelListData {
|
||||
enable: boolean
|
||||
@@ -63,7 +64,7 @@ export type AiProviderLlmsItems = {
|
||||
logo: string
|
||||
scopes: ('chat' | 'completions')[]
|
||||
config: string
|
||||
name?: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type AiProviderDefaultConfig = {
|
||||
|
||||
Reference in New Issue
Block a user