mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-07 02:55:08 +08:00
Feat: Add model verify (#13005)
### What problem does this PR solve? Feat: Add model verify ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Co-authored-by: Liu An <asiro@qq.com>
This commit is contained in:
@ -77,7 +77,14 @@ if (process.env.NODE_ENV === 'development') {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
retry: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
type Locale = ConfigProviderProps['locale'];
|
type Locale = ConfigProviderProps['locale'];
|
||||||
|
|
||||||
|
|||||||
@ -119,6 +119,7 @@ export const ConfirmDeleteDialogNode = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2.5">
|
<div className="flex flex-col gap-2.5">
|
||||||
|
{(avatar || name) && (
|
||||||
<div className="flex items-center border-0.5 text-text-secondary border-border-button rounded-lg px-3 py-4">
|
<div className="flex items-center border-0.5 text-text-secondary border-border-button rounded-lg px-3 py-4">
|
||||||
{avatar && (
|
{avatar && (
|
||||||
<RAGFlowAvatar
|
<RAGFlowAvatar
|
||||||
@ -130,6 +131,7 @@ export const ConfirmDeleteDialogNode = ({
|
|||||||
)}
|
)}
|
||||||
{name && <div className="ml-3">{name}</div>}
|
{name && <div className="ml-3">{name}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
{warnText && <div className="text-state-error text-xs">{warnText}</div>}
|
{warnText && <div className="text-state-error text-xs">{warnText}</div>}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -271,11 +271,12 @@ export interface IApiKeySavingParams {
|
|||||||
llm_name?: string;
|
llm_name?: string;
|
||||||
model_type?: string;
|
model_type?: string;
|
||||||
base_url?: string;
|
base_url?: string;
|
||||||
|
verify?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSaveApiKey = () => {
|
export const useSaveApiKey = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { t } = useTranslation();
|
// const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isPending: loading,
|
isPending: loading,
|
||||||
@ -285,14 +286,14 @@ export const useSaveApiKey = () => {
|
|||||||
mutationFn: async (params: IApiKeySavingParams) => {
|
mutationFn: async (params: IApiKeySavingParams) => {
|
||||||
const { data } = await userService.set_api_key(params);
|
const { data } = await userService.set_api_key(params);
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
message.success(t('message.modified'));
|
// message.success(t('message.modified'));
|
||||||
queryClient.invalidateQueries({ queryKey: [LLMApiAction.MyLlmList] });
|
queryClient.invalidateQueries({ queryKey: [LLMApiAction.MyLlmList] });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: [LLMApiAction.MyLlmListDetailed],
|
queryKey: [LLMApiAction.MyLlmListDetailed],
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({ queryKey: [LLMApiAction.FactoryList] });
|
queryClient.invalidateQueries({ queryKey: [LLMApiAction.FactoryList] });
|
||||||
}
|
}
|
||||||
return data.code;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -330,25 +331,25 @@ export const useSaveTenantInfo = () => {
|
|||||||
|
|
||||||
export const useAddLlm = () => {
|
export const useAddLlm = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { t } = useTranslation();
|
// const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
data,
|
data,
|
||||||
isPending: loading,
|
isPending: loading,
|
||||||
mutateAsync,
|
mutateAsync,
|
||||||
} = useMutation({
|
} = useMutation({
|
||||||
mutationKey: [LLMApiAction.AddLlm],
|
mutationKey: [LLMApiAction.AddLlm],
|
||||||
mutationFn: async (params: IAddLlmRequestBody) => {
|
mutationFn: async (params: IAddLlmRequestBody & { verify?: boolean }) => {
|
||||||
const { data } = await userService.add_llm(params);
|
const { data } = await userService.add_llm(params);
|
||||||
if (data.code === 0) {
|
if (data.code === 0 && !params.verify) {
|
||||||
queryClient.invalidateQueries({ queryKey: [LLMApiAction.MyLlmList] });
|
queryClient.invalidateQueries({ queryKey: [LLMApiAction.MyLlmList] });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: [LLMApiAction.MyLlmListDetailed],
|
queryKey: [LLMApiAction.MyLlmListDetailed],
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({ queryKey: [LLMApiAction.FactoryList] });
|
queryClient.invalidateQueries({ queryKey: [LLMApiAction.FactoryList] });
|
||||||
queryClient.invalidateQueries({ queryKey: [LLMApiAction.LlmList] });
|
queryClient.invalidateQueries({ queryKey: [LLMApiAction.LlmList] });
|
||||||
message.success(t('message.modified'));
|
// message.success(t('message.modified'));
|
||||||
}
|
}
|
||||||
return data.code;
|
return data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ export default {
|
|||||||
tokenPlaceholder: 'e.g. eyJhbGciOiJIUzI1Ni...',
|
tokenPlaceholder: 'e.g. eyJhbGciOiJIUzI1Ni...',
|
||||||
},
|
},
|
||||||
selected: 'Selected',
|
selected: 'Selected',
|
||||||
|
seeAll: 'See all',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
loginTitle: 'Sign in to your account',
|
loginTitle: 'Sign in to your account',
|
||||||
@ -889,6 +890,9 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s
|
|||||||
deleteSelectedConfirm: 'Delete the selected {count} session(s)?',
|
deleteSelectedConfirm: 'Delete the selected {count} session(s)?',
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
|
Verify: 'Verify',
|
||||||
|
keyValid: 'Your API key is valid.',
|
||||||
|
keyInvalid: 'Your API key is invalid.',
|
||||||
deleteModel: 'Delete model',
|
deleteModel: 'Delete model',
|
||||||
bedrockCredentialsHint:
|
bedrockCredentialsHint:
|
||||||
'Tip: Leave Access Key / Secret Key blank to use AWS IAM authentication.',
|
'Tip: Leave Access Key / Secret Key blank to use AWS IAM authentication.',
|
||||||
|
|||||||
@ -56,6 +56,7 @@ export default {
|
|||||||
zendeskDescription: '连接 Zendesk,同步工单、文章及其他内容。',
|
zendeskDescription: '连接 Zendesk,同步工单、文章及其他内容。',
|
||||||
promptPlaceholder: '请输入或使用 / 快速插入变量。',
|
promptPlaceholder: '请输入或使用 / 快速插入变量。',
|
||||||
selected: '已选择',
|
selected: '已选择',
|
||||||
|
seeAll: '查看全部',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
loginTitle: '登录账户',
|
loginTitle: '登录账户',
|
||||||
@ -835,6 +836,9 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
|||||||
deleteSelectedConfirm: '删除选中的 {count} 个会话?',
|
deleteSelectedConfirm: '删除选中的 {count} 个会话?',
|
||||||
},
|
},
|
||||||
setting: {
|
setting: {
|
||||||
|
Verify: '验证',
|
||||||
|
keyValid: '你的 API 密钥有效。',
|
||||||
|
keyInvalid: '你的 API 密钥无效。',
|
||||||
deleteModel: '删除模型',
|
deleteModel: '删除模型',
|
||||||
modelEmptyTip: '暂无可用模型,<br>请先在右侧面板添加模型。',
|
modelEmptyTip: '暂无可用模型,<br>请先在右侧面板添加模型。',
|
||||||
sourceEmptyTip: '暂未添加任何数据源,请从下方选择一个进行连接。',
|
sourceEmptyTip: '暂未添加任何数据源,请从下方选择一个进行连接。',
|
||||||
|
|||||||
@ -115,7 +115,7 @@ export const ModelProviderCard: FC<IModelCardProps> = ({
|
|||||||
content={{
|
content={{
|
||||||
node: (
|
node: (
|
||||||
<ConfirmDeleteDialogNode>
|
<ConfirmDeleteDialogNode>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2 border-0.5 text-text-secondary border-border-button rounded-lg px-3 py-4">
|
||||||
<LlmIcon name={item.name} />
|
<LlmIcon name={item.name} />
|
||||||
{item.name}
|
{item.name}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,31 +20,57 @@ import { ApiKeyPostBody } from '../interface';
|
|||||||
import { MinerUFormValues } from './modal/mineru-modal';
|
import { MinerUFormValues } from './modal/mineru-modal';
|
||||||
|
|
||||||
type SavingParamsState = Omit<IApiKeySavingParams, 'api_key'>;
|
type SavingParamsState = Omit<IApiKeySavingParams, 'api_key'>;
|
||||||
|
export type VerifyResult = {
|
||||||
|
isValid: boolean | null;
|
||||||
|
logs: string;
|
||||||
|
};
|
||||||
export const useSubmitApiKey = () => {
|
export const useSubmitApiKey = () => {
|
||||||
const [savingParams, setSavingParams] = useState<SavingParamsState>(
|
const [savingParams, setSavingParams] = useState<SavingParamsState>(
|
||||||
{} as SavingParamsState,
|
{} as SavingParamsState,
|
||||||
);
|
);
|
||||||
const [editMode, setEditMode] = useState(false);
|
const [editMode, setEditMode] = useState(false);
|
||||||
const { saveApiKey, loading } = useSaveApiKey();
|
const { saveApiKey } = useSaveApiKey();
|
||||||
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
const {
|
const {
|
||||||
visible: apiKeyVisible,
|
visible: apiKeyVisible,
|
||||||
hideModal: hideApiKeyModal,
|
hideModal: hideApiKeyModal,
|
||||||
showModal: showApiKeyModal,
|
showModal: showApiKeyModal,
|
||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const onApiKeySavingOk = useCallback(
|
const onApiKeySavingOk = useCallback(
|
||||||
async (postBody: ApiKeyPostBody) => {
|
async (postBody: ApiKeyPostBody, isVerify = false) => {
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
const ret = await saveApiKey({
|
const ret = await saveApiKey({
|
||||||
...savingParams,
|
...savingParams,
|
||||||
...postBody,
|
...postBody,
|
||||||
|
verify: isVerify,
|
||||||
});
|
});
|
||||||
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
queryClient.invalidateQueries({ queryKey: ['llmList'] });
|
queryClient.invalidateQueries({ queryKey: ['llmList'] });
|
||||||
hideApiKeyModal();
|
hideApiKeyModal();
|
||||||
setEditMode(false);
|
setEditMode(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideApiKeyModal, saveApiKey, savingParams, queryClient],
|
[hideApiKeyModal, saveApiKey, savingParams, queryClient],
|
||||||
);
|
);
|
||||||
@ -59,7 +85,7 @@ export const useSubmitApiKey = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
saveApiKeyLoading: loading,
|
saveApiKeyLoading: saveLoading,
|
||||||
initialApiKey: '',
|
initialApiKey: '',
|
||||||
llmFactory: savingParams.llm_factory,
|
llmFactory: savingParams.llm_factory,
|
||||||
editMode,
|
editMode,
|
||||||
@ -119,7 +145,8 @@ export const useSubmitOllama = () => {
|
|||||||
const [initialValues, setInitialValues] = useState<
|
const [initialValues, setInitialValues] = useState<
|
||||||
Partial<IAddLlmRequestBody> & { provider_order?: string }
|
Partial<IAddLlmRequestBody> & { provider_order?: string }
|
||||||
>();
|
>();
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: llmAddingVisible,
|
visible: llmAddingVisible,
|
||||||
hideModal: hideLlmAddingModal,
|
hideModal: hideLlmAddingModal,
|
||||||
@ -127,20 +154,41 @@ export const useSubmitOllama = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onLlmAddingOk = useCallback(
|
const onLlmAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
const cleanedPayload = { ...payload };
|
const cleanedPayload = { ...payload };
|
||||||
if (!cleanedPayload.api_key || cleanedPayload.api_key.trim() === '') {
|
if (!cleanedPayload.api_key || cleanedPayload.api_key.trim() === '') {
|
||||||
delete cleanedPayload.api_key;
|
delete cleanedPayload.api_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret = await addLlm(cleanedPayload);
|
const ret = await addLlm({ ...cleanedPayload, verify: isVerify });
|
||||||
if (ret === 0) {
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideLlmAddingModal();
|
hideLlmAddingModal();
|
||||||
setEditMode(false);
|
setEditMode(false);
|
||||||
setInitialValues(undefined);
|
setInitialValues(undefined);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideLlmAddingModal, addLlm],
|
[hideLlmAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleShowLlmAddingModal = (
|
const handleShowLlmAddingModal = (
|
||||||
@ -168,7 +216,7 @@ export const useSubmitOllama = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
llmAddingLoading: loading,
|
llmAddingLoading: saveLoading,
|
||||||
editMode,
|
editMode,
|
||||||
initialValues,
|
initialValues,
|
||||||
onLlmAddingOk,
|
onLlmAddingOk,
|
||||||
@ -180,7 +228,8 @@ export const useSubmitOllama = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitVolcEngine = () => {
|
export const useSubmitVolcEngine = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: volcAddingVisible,
|
visible: volcAddingVisible,
|
||||||
hideModal: hideVolcAddingModal,
|
hideModal: hideVolcAddingModal,
|
||||||
@ -188,17 +237,38 @@ export const useSubmitVolcEngine = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onVolcAddingOk = useCallback(
|
const onVolcAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideVolcAddingModal();
|
hideVolcAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideVolcAddingModal, addLlm],
|
[hideVolcAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
volcAddingLoading: loading,
|
volcAddingLoading: saveLoading,
|
||||||
onVolcAddingOk,
|
onVolcAddingOk,
|
||||||
volcAddingVisible,
|
volcAddingVisible,
|
||||||
hideVolcAddingModal,
|
hideVolcAddingModal,
|
||||||
@ -207,7 +277,8 @@ export const useSubmitVolcEngine = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitTencentCloud = () => {
|
export const useSubmitTencentCloud = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: TencentCloudAddingVisible,
|
visible: TencentCloudAddingVisible,
|
||||||
hideModal: hideTencentCloudAddingModal,
|
hideModal: hideTencentCloudAddingModal,
|
||||||
@ -215,17 +286,38 @@ export const useSubmitTencentCloud = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onTencentCloudAddingOk = useCallback(
|
const onTencentCloudAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideTencentCloudAddingModal();
|
hideTencentCloudAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideTencentCloudAddingModal, addLlm],
|
[hideTencentCloudAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
TencentCloudAddingLoading: loading,
|
TencentCloudAddingLoading: saveLoading,
|
||||||
onTencentCloudAddingOk,
|
onTencentCloudAddingOk,
|
||||||
TencentCloudAddingVisible,
|
TencentCloudAddingVisible,
|
||||||
hideTencentCloudAddingModal,
|
hideTencentCloudAddingModal,
|
||||||
@ -234,7 +326,8 @@ export const useSubmitTencentCloud = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitSpark = () => {
|
export const useSubmitSpark = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: SparkAddingVisible,
|
visible: SparkAddingVisible,
|
||||||
hideModal: hideSparkAddingModal,
|
hideModal: hideSparkAddingModal,
|
||||||
@ -242,17 +335,38 @@ export const useSubmitSpark = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onSparkAddingOk = useCallback(
|
const onSparkAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideSparkAddingModal();
|
hideSparkAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideSparkAddingModal, addLlm],
|
[hideSparkAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
SparkAddingLoading: loading,
|
SparkAddingLoading: saveLoading,
|
||||||
onSparkAddingOk,
|
onSparkAddingOk,
|
||||||
SparkAddingVisible,
|
SparkAddingVisible,
|
||||||
hideSparkAddingModal,
|
hideSparkAddingModal,
|
||||||
@ -261,7 +375,8 @@ export const useSubmitSpark = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmityiyan = () => {
|
export const useSubmityiyan = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: yiyanAddingVisible,
|
visible: yiyanAddingVisible,
|
||||||
hideModal: hideyiyanAddingModal,
|
hideModal: hideyiyanAddingModal,
|
||||||
@ -269,17 +384,38 @@ export const useSubmityiyan = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onyiyanAddingOk = useCallback(
|
const onyiyanAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideyiyanAddingModal();
|
hideyiyanAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideyiyanAddingModal, addLlm],
|
[hideyiyanAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
yiyanAddingLoading: loading,
|
yiyanAddingLoading: saveLoading,
|
||||||
onyiyanAddingOk,
|
onyiyanAddingOk,
|
||||||
yiyanAddingVisible,
|
yiyanAddingVisible,
|
||||||
hideyiyanAddingModal,
|
hideyiyanAddingModal,
|
||||||
@ -288,7 +424,8 @@ export const useSubmityiyan = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitFishAudio = () => {
|
export const useSubmitFishAudio = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: FishAudioAddingVisible,
|
visible: FishAudioAddingVisible,
|
||||||
hideModal: hideFishAudioAddingModal,
|
hideModal: hideFishAudioAddingModal,
|
||||||
@ -296,17 +433,38 @@ export const useSubmitFishAudio = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onFishAudioAddingOk = useCallback(
|
const onFishAudioAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideFishAudioAddingModal();
|
hideFishAudioAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideFishAudioAddingModal, addLlm],
|
[hideFishAudioAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
FishAudioAddingLoading: loading,
|
FishAudioAddingLoading: saveLoading,
|
||||||
onFishAudioAddingOk,
|
onFishAudioAddingOk,
|
||||||
FishAudioAddingVisible,
|
FishAudioAddingVisible,
|
||||||
hideFishAudioAddingModal,
|
hideFishAudioAddingModal,
|
||||||
@ -315,7 +473,8 @@ export const useSubmitFishAudio = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitGoogle = () => {
|
export const useSubmitGoogle = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: GoogleAddingVisible,
|
visible: GoogleAddingVisible,
|
||||||
hideModal: hideGoogleAddingModal,
|
hideModal: hideGoogleAddingModal,
|
||||||
@ -323,17 +482,38 @@ export const useSubmitGoogle = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onGoogleAddingOk = useCallback(
|
const onGoogleAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideGoogleAddingModal();
|
hideGoogleAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideGoogleAddingModal, addLlm],
|
[hideGoogleAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
GoogleAddingLoading: loading,
|
GoogleAddingLoading: saveLoading,
|
||||||
onGoogleAddingOk,
|
onGoogleAddingOk,
|
||||||
GoogleAddingVisible,
|
GoogleAddingVisible,
|
||||||
hideGoogleAddingModal,
|
hideGoogleAddingModal,
|
||||||
@ -342,7 +522,8 @@ export const useSubmitGoogle = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitBedrock = () => {
|
export const useSubmitBedrock = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: bedrockAddingVisible,
|
visible: bedrockAddingVisible,
|
||||||
hideModal: hideBedrockAddingModal,
|
hideModal: hideBedrockAddingModal,
|
||||||
@ -350,17 +531,38 @@ export const useSubmitBedrock = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onBedrockAddingOk = useCallback(
|
const onBedrockAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideBedrockAddingModal();
|
hideBedrockAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideBedrockAddingModal, addLlm],
|
[hideBedrockAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bedrockAddingLoading: loading,
|
bedrockAddingLoading: saveLoading,
|
||||||
onBedrockAddingOk,
|
onBedrockAddingOk,
|
||||||
bedrockAddingVisible,
|
bedrockAddingVisible,
|
||||||
hideBedrockAddingModal,
|
hideBedrockAddingModal,
|
||||||
@ -369,7 +571,8 @@ export const useSubmitBedrock = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitAzure = () => {
|
export const useSubmitAzure = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: AzureAddingVisible,
|
visible: AzureAddingVisible,
|
||||||
hideModal: hideAzureAddingModal,
|
hideModal: hideAzureAddingModal,
|
||||||
@ -377,17 +580,38 @@ export const useSubmitAzure = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onAzureAddingOk = useCallback(
|
const onAzureAddingOk = useCallback(
|
||||||
async (payload: IAddLlmRequestBody) => {
|
async (payload: IAddLlmRequestBody, isVerify = false) => {
|
||||||
const ret = await addLlm(payload);
|
if (!isVerify) {
|
||||||
if (ret === 0) {
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
|
const ret = await addLlm({ ...payload, verify: isVerify });
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideAzureAddingModal();
|
hideAzureAddingModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[hideAzureAddingModal, addLlm],
|
[hideAzureAddingModal, addLlm, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
AzureAddingLoading: loading,
|
AzureAddingLoading: saveLoading,
|
||||||
onAzureAddingOk,
|
onAzureAddingOk,
|
||||||
AzureAddingVisible,
|
AzureAddingVisible,
|
||||||
hideAzureAddingModal,
|
hideAzureAddingModal,
|
||||||
@ -436,7 +660,8 @@ export const useHandleDeleteFactory = (llmFactory: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitMinerU = () => {
|
export const useSubmitMinerU = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: mineruVisible,
|
visible: mineruVisible,
|
||||||
hideModal: hideMineruModal,
|
hideModal: hideMineruModal,
|
||||||
@ -444,7 +669,10 @@ export const useSubmitMinerU = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onMineruOk = useCallback(
|
const onMineruOk = useCallback(
|
||||||
async (payload: MinerUFormValues) => {
|
async (payload: MinerUFormValues, isVerify = false) => {
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
const cfg: any = {
|
const cfg: any = {
|
||||||
...payload,
|
...payload,
|
||||||
mineru_delete_output:
|
mineru_delete_output:
|
||||||
@ -461,12 +689,30 @@ export const useSubmitMinerU = () => {
|
|||||||
api_base: '',
|
api_base: '',
|
||||||
max_tokens: 0,
|
max_tokens: 0,
|
||||||
};
|
};
|
||||||
const ret = await addLlm(req);
|
const ret = await addLlm({ ...req, verify: isVerify });
|
||||||
if (ret === 0) {
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hideMineruModal();
|
hideMineruModal();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[addLlm, hideMineruModal],
|
[addLlm, hideMineruModal, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -474,12 +720,13 @@ export const useSubmitMinerU = () => {
|
|||||||
hideMineruModal,
|
hideMineruModal,
|
||||||
showMineruModal,
|
showMineruModal,
|
||||||
onMineruOk,
|
onMineruOk,
|
||||||
mineruLoading: loading,
|
mineruLoading: saveLoading,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSubmitPaddleOCR = () => {
|
export const useSubmitPaddleOCR = () => {
|
||||||
const { addLlm, loading } = useAddLlm();
|
const [saveLoading, setSaveLoading] = useState(false);
|
||||||
|
const { addLlm } = useAddLlm();
|
||||||
const {
|
const {
|
||||||
visible: paddleocrVisible,
|
visible: paddleocrVisible,
|
||||||
hideModal: hidePaddleOCRModal,
|
hideModal: hidePaddleOCRModal,
|
||||||
@ -487,7 +734,10 @@ export const useSubmitPaddleOCR = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const onPaddleOCROk = useCallback(
|
const onPaddleOCROk = useCallback(
|
||||||
async (payload: any) => {
|
async (payload: any, isVerify = false) => {
|
||||||
|
if (!isVerify) {
|
||||||
|
setSaveLoading(true);
|
||||||
|
}
|
||||||
const cfg: any = {
|
const cfg: any = {
|
||||||
...payload,
|
...payload,
|
||||||
};
|
};
|
||||||
@ -499,14 +749,32 @@ export const useSubmitPaddleOCR = () => {
|
|||||||
api_base: '',
|
api_base: '',
|
||||||
max_tokens: 0,
|
max_tokens: 0,
|
||||||
};
|
};
|
||||||
const ret = await addLlm(req);
|
const ret = await addLlm({ ...req, verify: isVerify });
|
||||||
if (ret === 0) {
|
if (!isVerify) {
|
||||||
|
setSaveLoading(false);
|
||||||
|
if (ret.code === 0) {
|
||||||
hidePaddleOCRModal();
|
hidePaddleOCRModal();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isVerify) {
|
||||||
|
let res = {} as VerifyResult;
|
||||||
|
if (ret.data?.success) {
|
||||||
|
res = {
|
||||||
|
isValid: true,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
isValid: false,
|
||||||
|
logs: ret.data?.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[addLlm, hidePaddleOCRModal],
|
[addLlm, hidePaddleOCRModal, setSaveLoading],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -514,6 +782,37 @@ export const useSubmitPaddleOCR = () => {
|
|||||||
hidePaddleOCRModal,
|
hidePaddleOCRModal,
|
||||||
showPaddleOCRModal,
|
showPaddleOCRModal,
|
||||||
onPaddleOCROk,
|
onPaddleOCROk,
|
||||||
paddleocrLoading: loading,
|
paddleocrLoading: saveLoading,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useVerifySettings = ({
|
||||||
|
onVerify,
|
||||||
|
}: {
|
||||||
|
onVerify:
|
||||||
|
| ((
|
||||||
|
postBody: ApiKeyPostBody,
|
||||||
|
isVerify?: boolean,
|
||||||
|
) => Promise<VerifyResult | undefined>)
|
||||||
|
| ((
|
||||||
|
payload: IAddLlmRequestBody,
|
||||||
|
isVerify?: boolean,
|
||||||
|
) => Promise<VerifyResult | undefined>)
|
||||||
|
| ((
|
||||||
|
payload: MinerUFormValues,
|
||||||
|
isVerify?: boolean,
|
||||||
|
) => Promise<VerifyResult | undefined>)
|
||||||
|
| ((payload: any, isVerify?: boolean) => Promise<boolean | VerifyResult>)
|
||||||
|
| (() => void);
|
||||||
|
}) => {
|
||||||
|
const onApiKeyVerifying = useCallback(
|
||||||
|
async (postBody: any) => {
|
||||||
|
const res = await onVerify(postBody, true);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
[onVerify],
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
onApiKeyVerifying,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
useSubmitTencentCloud,
|
useSubmitTencentCloud,
|
||||||
useSubmitVolcEngine,
|
useSubmitVolcEngine,
|
||||||
useSubmityiyan,
|
useSubmityiyan,
|
||||||
|
useVerifySettings,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
import ApiKeyModal from './modal/api-key-modal';
|
import ApiKeyModal from './modal/api-key-modal';
|
||||||
import AzureOpenAIModal from './modal/azure-openai-modal';
|
import AzureOpenAIModal from './modal/azure-openai-modal';
|
||||||
@ -204,6 +205,76 @@ const ModelProviders = () => {
|
|||||||
},
|
},
|
||||||
[showApiKeyModal, showLlmAddingModal, ModalMap, detailedLlmList],
|
[showApiKeyModal, showLlmAddingModal, ModalMap, detailedLlmList],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleOk = useMemo(() => {
|
||||||
|
if (apiKeyVisible) {
|
||||||
|
return onApiKeySavingOk;
|
||||||
|
}
|
||||||
|
if (llmAddingVisible) {
|
||||||
|
return onLlmAddingOk;
|
||||||
|
}
|
||||||
|
if (volcAddingVisible) {
|
||||||
|
return onVolcAddingOk;
|
||||||
|
}
|
||||||
|
if (TencentCloudAddingVisible) {
|
||||||
|
return onTencentCloudAddingOk;
|
||||||
|
}
|
||||||
|
if (SparkAddingVisible) {
|
||||||
|
return onSparkAddingOk;
|
||||||
|
}
|
||||||
|
if (yiyanAddingVisible) {
|
||||||
|
return onyiyanAddingOk;
|
||||||
|
}
|
||||||
|
if (FishAudioAddingVisible) {
|
||||||
|
return onFishAudioAddingOk;
|
||||||
|
}
|
||||||
|
if (bedrockAddingVisible) {
|
||||||
|
return onBedrockAddingOk;
|
||||||
|
}
|
||||||
|
if (AzureAddingVisible) {
|
||||||
|
return onAzureAddingOk;
|
||||||
|
}
|
||||||
|
if (mineruVisible) {
|
||||||
|
return onMineruOk;
|
||||||
|
}
|
||||||
|
if (paddleocrVisible) {
|
||||||
|
return onPaddleOCROk;
|
||||||
|
}
|
||||||
|
if (GoogleAddingVisible) {
|
||||||
|
return onGoogleAddingOk;
|
||||||
|
}
|
||||||
|
return () => {};
|
||||||
|
}, [
|
||||||
|
GoogleAddingVisible,
|
||||||
|
onGoogleAddingOk,
|
||||||
|
apiKeyVisible,
|
||||||
|
onApiKeySavingOk,
|
||||||
|
llmAddingVisible,
|
||||||
|
onLlmAddingOk,
|
||||||
|
volcAddingVisible,
|
||||||
|
onVolcAddingOk,
|
||||||
|
TencentCloudAddingVisible,
|
||||||
|
onTencentCloudAddingOk,
|
||||||
|
SparkAddingVisible,
|
||||||
|
onSparkAddingOk,
|
||||||
|
yiyanAddingVisible,
|
||||||
|
onyiyanAddingOk,
|
||||||
|
FishAudioAddingVisible,
|
||||||
|
onFishAudioAddingOk,
|
||||||
|
bedrockAddingVisible,
|
||||||
|
onBedrockAddingOk,
|
||||||
|
AzureAddingVisible,
|
||||||
|
onAzureAddingOk,
|
||||||
|
mineruVisible,
|
||||||
|
onMineruOk,
|
||||||
|
paddleocrVisible,
|
||||||
|
onPaddleOCROk,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { onApiKeyVerifying } = useVerifySettings({
|
||||||
|
onVerify: handleOk,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full border-[0.5px] border-border-button rounded-lg relative ">
|
<div className="flex w-full border-[0.5px] border-border-button rounded-lg relative ">
|
||||||
<Spotlight />
|
<Spotlight />
|
||||||
@ -227,6 +298,7 @@ const ModelProviders = () => {
|
|||||||
initialValue={initialApiKey}
|
initialValue={initialApiKey}
|
||||||
editMode={editMode}
|
editMode={editMode}
|
||||||
onOk={onApiKeySavingOk}
|
onOk={onApiKeySavingOk}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
llmFactory={llmFactory}
|
llmFactory={llmFactory}
|
||||||
></ApiKeyModal>
|
></ApiKeyModal>
|
||||||
{llmAddingVisible && (
|
{llmAddingVisible && (
|
||||||
@ -238,6 +310,7 @@ const ModelProviders = () => {
|
|||||||
editMode={llmEditMode}
|
editMode={llmEditMode}
|
||||||
initialValues={llmInitialValues}
|
initialValues={llmInitialValues}
|
||||||
llmFactory={selectedLlmFactory}
|
llmFactory={selectedLlmFactory}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></OllamaModal>
|
></OllamaModal>
|
||||||
)}
|
)}
|
||||||
<VolcEngineModal
|
<VolcEngineModal
|
||||||
@ -246,6 +319,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onVolcAddingOk}
|
onOk={onVolcAddingOk}
|
||||||
loading={volcAddingLoading}
|
loading={volcAddingLoading}
|
||||||
llmFactory={LLMFactory.VolcEngine}
|
llmFactory={LLMFactory.VolcEngine}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></VolcEngineModal>
|
></VolcEngineModal>
|
||||||
<GoogleModal
|
<GoogleModal
|
||||||
visible={GoogleAddingVisible}
|
visible={GoogleAddingVisible}
|
||||||
@ -253,6 +327,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onGoogleAddingOk}
|
onOk={onGoogleAddingOk}
|
||||||
loading={GoogleAddingLoading}
|
loading={GoogleAddingLoading}
|
||||||
llmFactory={LLMFactory.GoogleCloud}
|
llmFactory={LLMFactory.GoogleCloud}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></GoogleModal>
|
></GoogleModal>
|
||||||
<TencentCloudModal
|
<TencentCloudModal
|
||||||
visible={TencentCloudAddingVisible}
|
visible={TencentCloudAddingVisible}
|
||||||
@ -260,6 +335,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onTencentCloudAddingOk}
|
onOk={onTencentCloudAddingOk}
|
||||||
loading={TencentCloudAddingLoading}
|
loading={TencentCloudAddingLoading}
|
||||||
llmFactory={LLMFactory.TencentCloud}
|
llmFactory={LLMFactory.TencentCloud}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></TencentCloudModal>
|
></TencentCloudModal>
|
||||||
<SparkModal
|
<SparkModal
|
||||||
visible={SparkAddingVisible}
|
visible={SparkAddingVisible}
|
||||||
@ -267,6 +343,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onSparkAddingOk}
|
onOk={onSparkAddingOk}
|
||||||
loading={SparkAddingLoading}
|
loading={SparkAddingLoading}
|
||||||
llmFactory={LLMFactory.XunFeiSpark}
|
llmFactory={LLMFactory.XunFeiSpark}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></SparkModal>
|
></SparkModal>
|
||||||
<YiyanModal
|
<YiyanModal
|
||||||
visible={yiyanAddingVisible}
|
visible={yiyanAddingVisible}
|
||||||
@ -274,6 +351,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onyiyanAddingOk}
|
onOk={onyiyanAddingOk}
|
||||||
loading={yiyanAddingLoading}
|
loading={yiyanAddingLoading}
|
||||||
llmFactory={LLMFactory.BaiduYiYan}
|
llmFactory={LLMFactory.BaiduYiYan}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></YiyanModal>
|
></YiyanModal>
|
||||||
<FishAudioModal
|
<FishAudioModal
|
||||||
visible={FishAudioAddingVisible}
|
visible={FishAudioAddingVisible}
|
||||||
@ -281,6 +359,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onFishAudioAddingOk}
|
onOk={onFishAudioAddingOk}
|
||||||
loading={FishAudioAddingLoading}
|
loading={FishAudioAddingLoading}
|
||||||
llmFactory={LLMFactory.FishAudio}
|
llmFactory={LLMFactory.FishAudio}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></FishAudioModal>
|
></FishAudioModal>
|
||||||
<BedrockModal
|
<BedrockModal
|
||||||
visible={bedrockAddingVisible}
|
visible={bedrockAddingVisible}
|
||||||
@ -288,6 +367,7 @@ const ModelProviders = () => {
|
|||||||
onOk={onBedrockAddingOk}
|
onOk={onBedrockAddingOk}
|
||||||
loading={bedrockAddingLoading}
|
loading={bedrockAddingLoading}
|
||||||
llmFactory={LLMFactory.Bedrock}
|
llmFactory={LLMFactory.Bedrock}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></BedrockModal>
|
></BedrockModal>
|
||||||
<AzureOpenAIModal
|
<AzureOpenAIModal
|
||||||
visible={AzureAddingVisible}
|
visible={AzureAddingVisible}
|
||||||
@ -295,18 +375,21 @@ const ModelProviders = () => {
|
|||||||
onOk={onAzureAddingOk}
|
onOk={onAzureAddingOk}
|
||||||
loading={AzureAddingLoading}
|
loading={AzureAddingLoading}
|
||||||
llmFactory={LLMFactory.AzureOpenAI}
|
llmFactory={LLMFactory.AzureOpenAI}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></AzureOpenAIModal>
|
></AzureOpenAIModal>
|
||||||
<MinerUModal
|
<MinerUModal
|
||||||
visible={mineruVisible}
|
visible={mineruVisible}
|
||||||
hideModal={hideMineruModal}
|
hideModal={hideMineruModal}
|
||||||
onOk={onMineruOk}
|
onOk={onMineruOk}
|
||||||
loading={mineruLoading}
|
loading={mineruLoading}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></MinerUModal>
|
></MinerUModal>
|
||||||
<PaddleOCRModal
|
<PaddleOCRModal
|
||||||
visible={paddleocrVisible}
|
visible={paddleocrVisible}
|
||||||
hideModal={hidePaddleOCRModal}
|
hideModal={hidePaddleOCRModal}
|
||||||
onOk={onPaddleOCROk}
|
onOk={onPaddleOCROk}
|
||||||
loading={paddleocrLoading}
|
loading={paddleocrLoading}
|
||||||
|
onVerify={onApiKeyVerifying}
|
||||||
></PaddleOCRModal>
|
></PaddleOCRModal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import { KeyboardEventHandler, useCallback, useEffect } from 'react';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { ApiKeyPostBody } from '../../../interface';
|
import { ApiKeyPostBody } from '../../../interface';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import { VerifyResult } from '../../hooks';
|
||||||
|
import VerifyButton from '../verify-button';
|
||||||
|
|
||||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@ -22,6 +24,9 @@ interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
|||||||
llmFactory: string;
|
llmFactory: string;
|
||||||
editMode?: boolean;
|
editMode?: boolean;
|
||||||
onOk: (postBody: ApiKeyPostBody) => void;
|
onOk: (postBody: ApiKeyPostBody) => void;
|
||||||
|
onVerify: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
showModal?(): void;
|
showModal?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +51,7 @@ const ApiKeyModal = ({
|
|||||||
initialValue,
|
initialValue,
|
||||||
editMode = false,
|
editMode = false,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
}: IProps) => {
|
}: IProps) => {
|
||||||
const form = useForm<FieldType>();
|
const form = useForm<FieldType>();
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
@ -181,6 +187,8 @@ const ApiKeyModal = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<VerifyButton onVerify={onVerify} />
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
|
DynamicFormRef,
|
||||||
FormFieldConfig,
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
@ -8,19 +9,29 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const AzureOpenAIModal = ({
|
const AzureOpenAIModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tg } = useCommonTranslation();
|
const { t: tg } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
|
const formRef = useRef<DynamicFormRef>(null);
|
||||||
|
|
||||||
const fields: FormFieldConfig[] = [
|
const fields: FormFieldConfig[] = [
|
||||||
{
|
{
|
||||||
@ -114,6 +125,27 @@ const AzureOpenAIModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = formRef.current?.getValues();
|
||||||
|
const modelType =
|
||||||
|
values.model_type === 'chat' && values.vision
|
||||||
|
? 'image2text'
|
||||||
|
: values.model_type;
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
model_type: modelType,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -127,6 +159,7 @@ const AzureOpenAIModal = ({
|
|||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}}
|
}}
|
||||||
|
ref={formRef}
|
||||||
defaultValues={
|
defaultValues={
|
||||||
{
|
{
|
||||||
model_type: 'embedding',
|
model_type: 'embedding',
|
||||||
@ -137,6 +170,8 @@ const AzureOpenAIModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
<>
|
||||||
|
{onVerify && <VerifyButton onVerify={handleVerify} />}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
||||||
<DynamicForm.CancelButton
|
<DynamicForm.CancelButton
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
@ -151,9 +186,10 @@ const AzureOpenAIModal = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
</DynamicForm.Root>
|
</DynamicForm.Root>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AzureOpenAIModal;
|
export default memo(AzureOpenAIModal);
|
||||||
|
|||||||
@ -9,12 +9,14 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
import { BedrockRegionList } from '../../constant';
|
import { BedrockRegionList } from '../../constant';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
type FieldType = IAddLlmRequestBody & {
|
type FieldType = IAddLlmRequestBody & {
|
||||||
auth_mode?: 'access_key_secret' | 'iam_role' | 'assume_role';
|
auth_mode?: 'access_key_secret' | 'iam_role' | 'assume_role';
|
||||||
@ -28,9 +30,15 @@ const BedrockModal = ({
|
|||||||
visible = false,
|
visible = false,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: ct } = useCommonTranslation();
|
const { t: ct } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
@ -130,6 +138,40 @@ const BedrockModal = ({
|
|||||||
onOk?.(data as unknown as IAddLlmRequestBody);
|
onOk?.(data as unknown as IAddLlmRequestBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = form.getValues();
|
||||||
|
const cleanedValues: Record<string, any> = { ...values };
|
||||||
|
const fieldsByMode: Record<string, string[]> = {
|
||||||
|
access_key_secret: ['bedrock_ak', 'bedrock_sk'],
|
||||||
|
iam_role: ['aws_role_arn'],
|
||||||
|
assume_role: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
cleanedValues.auth_mode = authMode;
|
||||||
|
|
||||||
|
Object.keys(fieldsByMode).forEach((mode) => {
|
||||||
|
if (mode !== authMode) {
|
||||||
|
fieldsByMode[mode].forEach((field) => {
|
||||||
|
delete cleanedValues[field];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
...cleanedValues,
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
max_tokens: values.max_tokens,
|
||||||
|
};
|
||||||
|
}, [llmFactory, authMode, form]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -262,10 +304,11 @@ const BedrockModal = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
|
{onVerify && <VerifyButton onVerify={handleVerify} />}
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BedrockModal;
|
export default memo(BedrockModal);
|
||||||
|
|||||||
@ -8,16 +8,25 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const FishAudioModal = ({
|
const FishAudioModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
@ -85,6 +94,14 @@ const FishAudioModal = ({
|
|||||||
await onOk?.(data as IAddLlmRequestBody);
|
await onOk?.(data as IAddLlmRequestBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const res = await onVerify?.({ ...params, llm_factory: llmFactory });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[llmFactory, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -100,6 +117,9 @@ const FishAudioModal = ({
|
|||||||
defaultValues={{ model_type: 'tts' }}
|
defaultValues={{ model_type: 'tts' }}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton onVerify={handleVerify} isAbsolute={false} />
|
||||||
|
)}
|
||||||
<div className="flex items-center justify-between w-full">
|
<div className="flex items-center justify-between w-full">
|
||||||
<a
|
<a
|
||||||
href="https://fish.audio"
|
href="https://fish.audio"
|
||||||
@ -123,4 +143,4 @@ const FishAudioModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FishAudioModal;
|
export default memo(FishAudioModal);
|
||||||
|
|||||||
@ -8,16 +8,25 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const GoogleModal = ({
|
const GoogleModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
@ -112,6 +121,20 @@ const GoogleModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -132,6 +155,7 @@ const GoogleModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && <VerifyButton onVerify={handleVerify} />}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
||||||
<DynamicForm.CancelButton
|
<DynamicForm.CancelButton
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
@ -151,4 +175,4 @@ const GoogleModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GoogleModal;
|
export default memo(GoogleModal);
|
||||||
|
|||||||
@ -13,13 +13,16 @@ import { RAGFlowSelect } from '@/components/ui/select';
|
|||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
import { LLMFactory } from '@/constants/llm';
|
import { LLMFactory } from '@/constants/llm';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../verify-button';
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
llm_name: z.string().min(1, {
|
llm_name: z.string().min(1, {
|
||||||
@ -46,8 +49,13 @@ const MinerUModal = ({
|
|||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
}: IModalProps<MinerUFormValues>) => {
|
}: IModalProps<MinerUFormValues> & {
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const backendOptions = buildOptions([
|
const backendOptions = buildOptions([
|
||||||
@ -152,16 +160,23 @@ const MinerUModal = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton
|
||||||
|
onVerify={onVerify as (postBody: any) => Promise<VerifyResult>}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<div className="flex gap-2">
|
||||||
<ButtonLoading type="submit" form="mineru-form" loading={loading}>
|
<ButtonLoading type="submit" form="mineru-form" loading={loading}>
|
||||||
{t('common.save', 'Save')}
|
{t('common.save', 'Save')}
|
||||||
</ButtonLoading>
|
</ButtonLoading>
|
||||||
|
</div>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MinerUModal;
|
export default memo(MinerUModal);
|
||||||
|
|||||||
@ -8,17 +8,24 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const TencentCloudModal = ({
|
const TencentCloudModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<Omit<IAddLlmRequestBody, 'max_tokens'>> & {
|
}: IModalProps<Omit<IAddLlmRequestBody, 'max_tokens'>> & {
|
||||||
llmFactory: string;
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
@ -108,6 +115,21 @@ const TencentCloudModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -127,6 +149,9 @@ const TencentCloudModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton onVerify={handleVerify} isAbsolute={false} />
|
||||||
|
)}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-between w-full py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-between w-full py-6 px-6">
|
||||||
<a
|
<a
|
||||||
href="https://cloud.tencent.com/document/api/1093/37823"
|
href="https://cloud.tencent.com/document/api/1093/37823"
|
||||||
@ -156,4 +181,4 @@ const TencentCloudModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TencentCloudModal;
|
export default memo(TencentCloudModal);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
|
DynamicFormRef,
|
||||||
FormFieldConfig,
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
@ -9,9 +10,11 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
import { useMemo } from 'react';
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const llmFactoryToUrlMap: Partial<Record<LLMFactory, string>> = {
|
const llmFactoryToUrlMap: Partial<Record<LLMFactory, string>> = {
|
||||||
[LLMFactory.Ollama]:
|
[LLMFactory.Ollama]:
|
||||||
@ -38,6 +41,7 @@ const OllamaModal = ({
|
|||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
editMode = false,
|
editMode = false,
|
||||||
@ -45,10 +49,14 @@ const OllamaModal = ({
|
|||||||
}: IModalProps<Partial<IAddLlmRequestBody> & { provider_order?: string }> & {
|
}: IModalProps<Partial<IAddLlmRequestBody> & { provider_order?: string }> & {
|
||||||
llmFactory: string;
|
llmFactory: string;
|
||||||
editMode?: boolean;
|
editMode?: boolean;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
|
const formRef = useRef<DynamicFormRef>(null);
|
||||||
|
|
||||||
const optionsMap: Partial<
|
const optionsMap: Partial<
|
||||||
Record<LLMFactory, { label: string; value: string }[]>
|
Record<LLMFactory, { label: string; value: string }[]>
|
||||||
@ -233,6 +241,27 @@ const OllamaModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = formRef.current?.getValues();
|
||||||
|
const modelType =
|
||||||
|
values.model_type === 'chat' && values.vision
|
||||||
|
? 'image2text'
|
||||||
|
: values.model_type;
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
model_type: modelType,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -245,10 +274,14 @@ const OllamaModal = ({
|
|||||||
<DynamicForm.Root
|
<DynamicForm.Root
|
||||||
key={`${visible}-${llmFactory}`}
|
key={`${visible}-${llmFactory}`}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
|
ref={formRef}
|
||||||
onSubmit={() => {}}
|
onSubmit={() => {}}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton onVerify={handleVerify} isAbsolute={false} />
|
||||||
|
)}
|
||||||
<div className="flex items-center justify-between w-full gap-2 ">
|
<div className="flex items-center justify-between w-full gap-2 ">
|
||||||
<a href={url} target="_blank" rel="noreferrer" className="text-sm">
|
<a href={url} target="_blank" rel="noreferrer" className="text-sm">
|
||||||
{t('ollamaLink', { name: llmFactory })}
|
{t('ollamaLink', { name: llmFactory })}
|
||||||
@ -273,4 +306,4 @@ const OllamaModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default OllamaModal;
|
export default memo(OllamaModal);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { RAGFlowFormItem } from '@/components/ragflow-form';
|
|||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog';
|
} from '@/components/ui/dialog';
|
||||||
@ -9,12 +10,15 @@ import { Form } from '@/components/ui/form';
|
|||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
|
import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
|
||||||
import { LLMFactory } from '@/constants/llm';
|
import { LLMFactory } from '@/constants/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
import { memo } from 'react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../verify-button';
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
llm_name: z.string().min(1, {
|
llm_name: z.string().min(1, {
|
||||||
@ -33,6 +37,9 @@ export interface IModalProps<T> {
|
|||||||
visible: boolean;
|
visible: boolean;
|
||||||
hideModal: () => void;
|
hideModal: () => void;
|
||||||
onOk?: (data: T) => Promise<boolean>;
|
onOk?: (data: T) => Promise<boolean>;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +51,7 @@ const PaddleOCRModal = ({
|
|||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
}: IModalProps<PaddleOCRFormValues>) => {
|
}: IModalProps<PaddleOCRFormValues>) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -113,6 +121,12 @@ const PaddleOCRModal = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton
|
||||||
|
onVerify={onVerify as (postBody: any) => Promise<VerifyResult>}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DialogFooter>
|
||||||
<div className="flex justify-end space-x-2">
|
<div className="flex justify-end space-x-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -129,6 +143,7 @@ const PaddleOCRModal = ({
|
|||||||
{t('common.add')}
|
{t('common.add')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
@ -136,4 +151,4 @@ const PaddleOCRModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PaddleOCRModal;
|
export default memo(PaddleOCRModal);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
|
DynamicFormRef,
|
||||||
FormFieldConfig,
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
@ -8,21 +9,30 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const SparkModal = ({
|
const SparkModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
|
const formRef = useRef<DynamicFormRef>(null);
|
||||||
const fields: FormFieldConfig[] = [
|
const fields: FormFieldConfig[] = [
|
||||||
{
|
{
|
||||||
name: 'model_type',
|
name: 'model_type',
|
||||||
@ -128,6 +138,27 @@ const SparkModal = ({
|
|||||||
await onOk?.(data as IAddLlmRequestBody);
|
await onOk?.(data as IAddLlmRequestBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = formRef.current?.getValues();
|
||||||
|
const modelType =
|
||||||
|
values.model_type === 'chat' && values.vision
|
||||||
|
? 'image2text'
|
||||||
|
: values.model_type;
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
model_type: modelType,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -141,6 +172,7 @@ const SparkModal = ({
|
|||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}}
|
}}
|
||||||
|
ref={formRef}
|
||||||
defaultValues={
|
defaultValues={
|
||||||
{
|
{
|
||||||
model_type: 'chat',
|
model_type: 'chat',
|
||||||
@ -149,6 +181,7 @@ const SparkModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && <VerifyButton onVerify={handleVerify} />}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
||||||
<DynamicForm.CancelButton
|
<DynamicForm.CancelButton
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
@ -168,4 +201,4 @@ const SparkModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SparkModal;
|
export default memo(SparkModal);
|
||||||
|
|||||||
@ -0,0 +1,123 @@
|
|||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { replaceText } from '@/pages/dataset/process-log-modal';
|
||||||
|
import { ApiKeyPostBody } from '@/pages/user-setting/interface';
|
||||||
|
import { RefreshCcw } from 'lucide-react';
|
||||||
|
import { memo, useCallback, useState } from 'react';
|
||||||
|
import { useFormContext } from 'react-hook-form';
|
||||||
|
import { VerifyResult } from '../../hooks';
|
||||||
|
|
||||||
|
interface IVerifyButton {
|
||||||
|
onVerify: (params: any) => Promise<VerifyResult>;
|
||||||
|
isAbsolute?: boolean;
|
||||||
|
params?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VerifyButton: React.FC<IVerifyButton> = ({
|
||||||
|
onVerify,
|
||||||
|
isAbsolute = true,
|
||||||
|
params,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslate('setting');
|
||||||
|
const [isVerifying, setIsVerifying] = useState(false);
|
||||||
|
const [verifyResult, setVerifyResult] = useState<VerifyResult | null>(null);
|
||||||
|
const form = useFormContext();
|
||||||
|
|
||||||
|
const onHandleVerify = useCallback(async () => {
|
||||||
|
const formValid = await form?.trigger();
|
||||||
|
if (!formValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// setVerifyLoading(true);
|
||||||
|
try {
|
||||||
|
const values = form.getValues();
|
||||||
|
const result = await onVerify({
|
||||||
|
...values,
|
||||||
|
verify: true,
|
||||||
|
...params,
|
||||||
|
} as ApiKeyPostBody & { verify: boolean });
|
||||||
|
setVerifyResult(result);
|
||||||
|
} catch (error: any) {
|
||||||
|
let logs = '';
|
||||||
|
|
||||||
|
if (error?.message) {
|
||||||
|
logs = error.message;
|
||||||
|
} else if (typeof error === 'string') {
|
||||||
|
logs = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
setVerifyResult({
|
||||||
|
isValid: false,
|
||||||
|
logs: logs,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
// setVerifyLoading(false);
|
||||||
|
}
|
||||||
|
}, [form, onVerify, params]);
|
||||||
|
const handleVerify = async () => {
|
||||||
|
setVerifyResult({
|
||||||
|
isValid: null,
|
||||||
|
logs: '',
|
||||||
|
});
|
||||||
|
setIsVerifying(true);
|
||||||
|
try {
|
||||||
|
await onHandleVerify();
|
||||||
|
} catch (error) {
|
||||||
|
setVerifyResult({
|
||||||
|
isValid: false,
|
||||||
|
logs: (error as Error).message || 'Unknown error',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsVerifying(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
!isAbsolute || (verifyResult && verifyResult.isValid === false)
|
||||||
|
? 'flex flex-col gap-5 w-full '
|
||||||
|
: 'absolute left-6 bottom-6 z-[100]',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex gap-2 items-center">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={handleVerify}
|
||||||
|
disabled={isVerifying}
|
||||||
|
variant={'ghost'}
|
||||||
|
>
|
||||||
|
<RefreshCcw
|
||||||
|
size={14}
|
||||||
|
className={cn(isVerifying ? 'animate-spin-reverse' : '', '')}
|
||||||
|
/>
|
||||||
|
{t('Verify')}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{verifyResult && verifyResult.isValid !== null && (
|
||||||
|
<div
|
||||||
|
className={`flex items-center gap-2 ${
|
||||||
|
verifyResult.isValid ? 'text-state-success' : 'text-state-error'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{verifyResult.isValid ? t('keyValid') : t('keyInvalid')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{verifyResult && verifyResult.isValid !== null && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{verifyResult.logs && (
|
||||||
|
<div className="w-full whitespace-pre-line text-wrap bg-bg-card rounded-lg h-fit max-h-[250px] overflow-y-auto scrollbar-auto p-2.5">
|
||||||
|
{replaceText(verifyResult.logs)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(VerifyButton);
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
|
DynamicFormRef,
|
||||||
FormFieldConfig,
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
@ -8,8 +9,11 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback, useRef } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
type VolcEngineLlmRequest = IAddLlmRequestBody & {
|
type VolcEngineLlmRequest = IAddLlmRequestBody & {
|
||||||
endpoint_id: string;
|
endpoint_id: string;
|
||||||
@ -20,13 +24,19 @@ const VolcEngineModal = ({
|
|||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
|
const formRef = useRef<DynamicFormRef>(null);
|
||||||
const fields: FormFieldConfig[] = [
|
const fields: FormFieldConfig[] = [
|
||||||
{
|
{
|
||||||
name: 'model_type',
|
name: 'model_type',
|
||||||
@ -91,6 +101,27 @@ const VolcEngineModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = formRef.current?.getValues();
|
||||||
|
const modelType =
|
||||||
|
values.model_type === 'chat' && values.vision
|
||||||
|
? 'image2text'
|
||||||
|
: values.model_type;
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
model_type: modelType,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
@ -104,6 +135,7 @@ const VolcEngineModal = ({
|
|||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}}
|
}}
|
||||||
|
ref={formRef}
|
||||||
defaultValues={
|
defaultValues={
|
||||||
{
|
{
|
||||||
model_type: 'chat',
|
model_type: 'chat',
|
||||||
@ -112,6 +144,9 @@ const VolcEngineModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
{onVerify && (
|
||||||
|
<VerifyButton onVerify={handleVerify} isAbsolute={false} />
|
||||||
|
)}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-between w-full py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-between w-full py-6 px-6">
|
||||||
<a
|
<a
|
||||||
href="https://www.volcengine.com/docs/82379/1302008"
|
href="https://www.volcengine.com/docs/82379/1302008"
|
||||||
@ -140,4 +175,4 @@ const VolcEngineModal = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VolcEngineModal;
|
export default memo(VolcEngineModal);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DynamicForm,
|
DynamicForm,
|
||||||
|
DynamicFormRef,
|
||||||
FormFieldConfig,
|
FormFieldConfig,
|
||||||
FormFieldType,
|
FormFieldType,
|
||||||
} from '@/components/dynamic-form';
|
} from '@/components/dynamic-form';
|
||||||
@ -8,21 +9,32 @@ import { useCommonTranslation, useTranslate } from '@/hooks/common-hooks';
|
|||||||
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
import { useBuildModelTypeOptions } from '@/hooks/logic-hooks/use-build-options';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||||
|
import { VerifyResult } from '@/pages/user-setting/setting-model/hooks';
|
||||||
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||||
import { FieldValues } from 'react-hook-form';
|
import { FieldValues } from 'react-hook-form';
|
||||||
import { LLMHeader } from '../../components/llm-header';
|
import { LLMHeader } from '../../components/llm-header';
|
||||||
|
import VerifyButton from '../../modal/verify-button';
|
||||||
|
|
||||||
const YiyanModal = ({
|
const YiyanModal = ({
|
||||||
visible,
|
visible,
|
||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
|
onVerify,
|
||||||
loading,
|
loading,
|
||||||
llmFactory,
|
llmFactory,
|
||||||
}: IModalProps<IAddLlmRequestBody> & { llmFactory: string }) => {
|
}: IModalProps<IAddLlmRequestBody> & {
|
||||||
|
llmFactory: string;
|
||||||
|
onVerify?: (
|
||||||
|
postBody: any,
|
||||||
|
) => Promise<boolean | void | VerifyResult | undefined>;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslate('setting');
|
const { t } = useTranslate('setting');
|
||||||
const { t: tc } = useCommonTranslation();
|
const { t: tc } = useCommonTranslation();
|
||||||
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
const { buildModelTypeOptions } = useBuildModelTypeOptions();
|
||||||
|
const formRef = useRef<DynamicFormRef>(null);
|
||||||
|
|
||||||
const fields: FormFieldConfig[] = [
|
const fields = useMemo<FormFieldConfig[]>(
|
||||||
|
() => [
|
||||||
{
|
{
|
||||||
name: 'model_type',
|
name: 'model_type',
|
||||||
label: t('modelType'),
|
label: t('modelType'),
|
||||||
@ -62,7 +74,9 @@ const YiyanModal = ({
|
|||||||
min: 0,
|
min: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
],
|
||||||
|
[t, buildModelTypeOptions],
|
||||||
|
);
|
||||||
|
|
||||||
const handleOk = async (values?: FieldValues) => {
|
const handleOk = async (values?: FieldValues) => {
|
||||||
if (!values) return;
|
if (!values) return;
|
||||||
@ -88,16 +102,47 @@ const YiyanModal = ({
|
|||||||
await onOk?.(data);
|
await onOk?.(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const verifyParamsFunc = useCallback(() => {
|
||||||
|
const values = formRef.current?.getValues();
|
||||||
|
const modelType =
|
||||||
|
values.model_type === 'chat' && values.vision
|
||||||
|
? 'image2text'
|
||||||
|
: values.model_type;
|
||||||
|
return {
|
||||||
|
llm_factory: llmFactory,
|
||||||
|
llm_name: values.llm_name as string,
|
||||||
|
model_type: modelType,
|
||||||
|
api_key: {
|
||||||
|
yiyan_ak: values.yiyan_ak,
|
||||||
|
yiyan_sk: values.yiyan_sk,
|
||||||
|
},
|
||||||
|
max_tokens: values.max_tokens as number,
|
||||||
|
};
|
||||||
|
}, [llmFactory]);
|
||||||
|
|
||||||
|
const handleVerify = useCallback(
|
||||||
|
async (params: any) => {
|
||||||
|
const verifyParams = verifyParamsFunc();
|
||||||
|
const res = await onVerify?.({ ...params, ...verifyParams });
|
||||||
|
return (res || { isValid: null, logs: '' }) as VerifyResult;
|
||||||
|
},
|
||||||
|
[verifyParamsFunc, onVerify],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
title={<LLMHeader name={llmFactory} />}
|
title={<LLMHeader name={llmFactory} />}
|
||||||
open={visible || false}
|
open={visible || false}
|
||||||
onOpenChange={(open) => !open && hideModal?.()}
|
onOpenChange={(open) => !open && hideModal?.()}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
footer={<div className="p-4"></div>}
|
// footer={<div className="p-4"></div>}
|
||||||
|
footer={<></>}
|
||||||
|
footerClassName="pb-10"
|
||||||
>
|
>
|
||||||
<DynamicForm.Root
|
<DynamicForm.Root
|
||||||
|
key={`${visible}-${llmFactory}`}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
|
ref={formRef}
|
||||||
onSubmit={(data) => {
|
onSubmit={(data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}}
|
}}
|
||||||
@ -109,6 +154,8 @@ const YiyanModal = ({
|
|||||||
}
|
}
|
||||||
labelClassName="font-normal"
|
labelClassName="font-normal"
|
||||||
>
|
>
|
||||||
|
<div>
|
||||||
|
{onVerify && <VerifyButton onVerify={handleVerify} />}
|
||||||
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
<div className="absolute bottom-0 right-0 left-0 flex items-center justify-end w-full gap-2 py-6 px-6">
|
||||||
<DynamicForm.CancelButton
|
<DynamicForm.CancelButton
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
@ -123,9 +170,10 @@ const YiyanModal = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</DynamicForm.Root>
|
</DynamicForm.Root>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default YiyanModal;
|
export default memo(YiyanModal);
|
||||||
|
|||||||
@ -211,11 +211,16 @@ module.exports = {
|
|||||||
'0%,70%,100%': { opacity: '1' },
|
'0%,70%,100%': { opacity: '1' },
|
||||||
'20%,50%': { opacity: '0' },
|
'20%,50%': { opacity: '0' },
|
||||||
},
|
},
|
||||||
|
'spin-reverse': {
|
||||||
|
from: { transform: 'rotate(0deg)' },
|
||||||
|
to: { transform: 'rotate(-360deg)' },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||||
'caret-blink': 'caret-blink 1.25s ease-out infinite',
|
'caret-blink': 'caret-blink 1.25s ease-out infinite',
|
||||||
|
'spin-reverse': 'spin-reverse 1s linear infinite',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user