mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Fix: Fixed the styling and logic issues on the model provider page ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -1,129 +0,0 @@
|
||||
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||
import { LLMFactory } from '@/constants/llm';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { Form, Input, Modal } from 'antd';
|
||||
import { KeyboardEventHandler, useCallback, useEffect } from 'react';
|
||||
import { ApiKeyPostBody } from '../../interface';
|
||||
|
||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
loading: boolean;
|
||||
initialValue: string;
|
||||
llmFactory: string;
|
||||
editMode?: boolean;
|
||||
onOk: (postBody: ApiKeyPostBody) => void;
|
||||
showModal?(): void;
|
||||
}
|
||||
|
||||
type FieldType = {
|
||||
api_key?: string;
|
||||
base_url?: string;
|
||||
group_id?: string;
|
||||
};
|
||||
|
||||
const modelsWithBaseUrl = [
|
||||
LLMFactory.OpenAI,
|
||||
LLMFactory.AzureOpenAI,
|
||||
LLMFactory.TongYiQianWen,
|
||||
];
|
||||
|
||||
const ApiKeyModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
llmFactory,
|
||||
loading,
|
||||
initialValue,
|
||||
editMode = false,
|
||||
onOk,
|
||||
}: IProps) => {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslate('setting');
|
||||
|
||||
const handleOk = useCallback(async () => {
|
||||
const ret = await form.validateFields();
|
||||
|
||||
return onOk(ret);
|
||||
}, [form, onOk]);
|
||||
|
||||
const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(
|
||||
async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
await handleOk();
|
||||
}
|
||||
},
|
||||
[handleOk],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
form.setFieldValue('api_key', initialValue);
|
||||
}
|
||||
}, [initialValue, form, visible]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={editMode ? t('editModel') : t('modify')}
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={hideModal}
|
||||
okButtonProps={{ loading }}
|
||||
confirmLoading={loading}
|
||||
>
|
||||
<Form
|
||||
name="basic"
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
style={{ maxWidth: 600 }}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label={t('apiKey')}
|
||||
name="api_key"
|
||||
tooltip={t('apiKeyTip')}
|
||||
rules={[{ required: true, message: t('apiKeyMessage') }]}
|
||||
>
|
||||
<Input onKeyDown={handleKeyDown} />
|
||||
</Form.Item>
|
||||
{modelsWithBaseUrl.some((x) => x === llmFactory) && (
|
||||
<Form.Item<FieldType>
|
||||
label={t('baseUrl')}
|
||||
name="base_url"
|
||||
tooltip={
|
||||
llmFactory === LLMFactory.TongYiQianWen
|
||||
? t('tongyiBaseUrlTip')
|
||||
: t('baseUrlTip')
|
||||
}
|
||||
>
|
||||
<Input
|
||||
placeholder={
|
||||
llmFactory === LLMFactory.TongYiQianWen
|
||||
? t('tongyiBaseUrlPlaceholder')
|
||||
: 'https://api.openai.com/v1'
|
||||
}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
{llmFactory?.toLowerCase() === 'Anthropic'.toLowerCase() && (
|
||||
<Form.Item<FieldType>
|
||||
label={t('baseUrl')}
|
||||
name="base_url"
|
||||
tooltip={t('baseUrlTip')}
|
||||
>
|
||||
<Input
|
||||
placeholder="https://api.anthropic.com/v1"
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
{llmFactory?.toLowerCase() === 'Minimax'.toLowerCase() && (
|
||||
<Form.Item<FieldType> label={'Group ID'} name="group_id">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApiKeyModal;
|
||||
@ -1,6 +1,7 @@
|
||||
// src/components/ModelProviderCard.tsx
|
||||
import { LlmIcon } from '@/components/svg-icon';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { useSetModalState, useTranslate } from '@/hooks/common-hooks';
|
||||
import { LlmItem } from '@/hooks/llm-hooks';
|
||||
import { getRealModelName } from '@/utils/llm-util';
|
||||
@ -8,7 +9,7 @@ import { EditOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
import { ChevronsDown, ChevronsUp, Trash2 } from 'lucide-react';
|
||||
import { FC } from 'react';
|
||||
import { isLocalLlmFactory } from '../../utils';
|
||||
import { useHandleDeleteFactory, useHandleDeleteLlm } from '../hooks';
|
||||
import { useHandleDeleteFactory, useHandleEnableLlm } from '../hooks';
|
||||
|
||||
interface IModelCardProps {
|
||||
item: LlmItem;
|
||||
@ -52,7 +53,7 @@ export const ModelProviderCard: FC<IModelCardProps> = ({
|
||||
}) => {
|
||||
const { visible, switchVisible } = useSetModalState();
|
||||
const { t } = useTranslate('setting');
|
||||
const { handleDeleteLlm } = useHandleDeleteLlm(item.name);
|
||||
const { handleEnableLlm } = useHandleEnableLlm(item.name);
|
||||
const { handleDeleteFactory } = useHandleDeleteFactory(item.name);
|
||||
|
||||
const handleApiKeyClick = () => {
|
||||
@ -66,7 +67,7 @@ export const ModelProviderCard: FC<IModelCardProps> = ({
|
||||
return (
|
||||
<div className={`w-full rounded-lg border border-border-default`}>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 cursor-pointer transition-colors">
|
||||
<div className="flex h-16 items-center justify-between p-4 cursor-pointer transition-colors">
|
||||
<div className="flex items-center space-x-3">
|
||||
<LlmIcon name={item.name} />
|
||||
<div>
|
||||
@ -151,16 +152,12 @@ export const ModelProviderCard: FC<IModelCardProps> = ({
|
||||
<EditOutlined />
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant={'secondary'}
|
||||
onClick={() => {
|
||||
handleDeleteLlm(model.name);
|
||||
console.log(handleDeleteLlm, model.name);
|
||||
<Switch
|
||||
checked={model.status === '1'}
|
||||
onCheckedChange={(value) => {
|
||||
handleEnableLlm(model.name, value);
|
||||
}}
|
||||
className="p-1 hover:text-state-error transition-colors"
|
||||
>
|
||||
<Trash2 />
|
||||
</Button>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -10,8 +10,8 @@ export const UsedModel = ({
|
||||
}) => {
|
||||
const { factoryList, myLlmList: llmList, loading } = useSelectLlmList();
|
||||
return (
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="text-text-primary text-2xl mb-4 mt-4">Added models</div>
|
||||
<div className="flex flex-col w-full gap-4 mb-4">
|
||||
<div className="text-text-primary text-2xl mb-2 mt-4">Added models</div>
|
||||
{llmList.map((llm) => {
|
||||
return (
|
||||
<ModelProviderCard
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
useAddLlm,
|
||||
useDeleteFactory,
|
||||
useDeleteLlm,
|
||||
useEnableLlm,
|
||||
useSaveApiKey,
|
||||
useSaveTenantInfo,
|
||||
useSelectLlmOptionsByModelType,
|
||||
@ -421,7 +422,7 @@ export const useHandleDeleteLlm = (llmFactory: string) => {
|
||||
const { deleteLlm } = useDeleteLlm();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
|
||||
const handleDeleteLlm = (name: string) => () => {
|
||||
const handleDeleteLlm = (name: string) => {
|
||||
showDeleteConfirm({
|
||||
onOk: async () => {
|
||||
deleteLlm({ llm_factory: llmFactory, llm_name: name });
|
||||
@ -432,6 +433,16 @@ export const useHandleDeleteLlm = (llmFactory: string) => {
|
||||
return { handleDeleteLlm };
|
||||
};
|
||||
|
||||
export const useHandleEnableLlm = (llmFactory: string) => {
|
||||
const { enableLlm } = useEnableLlm();
|
||||
|
||||
const handleEnableLlm = (name: string, enable: boolean) => {
|
||||
enableLlm({ llm_factory: llmFactory, llm_name: name, enable });
|
||||
};
|
||||
|
||||
return { handleEnableLlm };
|
||||
};
|
||||
|
||||
export const useHandleDeleteFactory = (llmFactory: string) => {
|
||||
const { deleteFactory } = useDeleteFactory();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
|
||||
@ -2,14 +2,9 @@ import { LLMFactory } from '@/constants/llm';
|
||||
import { LlmItem, useFetchMyLlmListDetailed } from '@/hooks/llm-hooks';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { isLocalLlmFactory } from '../utils';
|
||||
import ApiKeyModal from './api-key-modal';
|
||||
import AzureOpenAIModal from './azure-openai-modal';
|
||||
import BedrockModal from './bedrock-modal';
|
||||
import SystemSetting from './components/system-setting';
|
||||
import { AvailableModels } from './components/un-add-model';
|
||||
import { UsedModel } from './components/used-model';
|
||||
import FishAudioModal from './fish-audio-modal';
|
||||
import GoogleModal from './google-modal';
|
||||
import {
|
||||
useSubmitApiKey,
|
||||
useSubmitAzure,
|
||||
@ -24,12 +19,17 @@ import {
|
||||
useSubmitVolcEngine,
|
||||
useSubmityiyan,
|
||||
} from './hooks';
|
||||
import HunyuanModal from './hunyuan-modal';
|
||||
import TencentCloudModal from './next-tencent-modal';
|
||||
import OllamaModal from './ollama-modal';
|
||||
import SparkModal from './spark-modal';
|
||||
import VolcEngineModal from './volcengine-modal';
|
||||
import YiyanModal from './yiyan-modal';
|
||||
import ApiKeyModal from './modal/api-key-modal';
|
||||
import AzureOpenAIModal from './modal/azure-openai-modal';
|
||||
import BedrockModal from './modal/bedrock-modal';
|
||||
import FishAudioModal from './modal/fish-audio-modal';
|
||||
import GoogleModal from './modal/google-modal';
|
||||
import HunyuanModal from './modal/hunyuan-modal';
|
||||
import TencentCloudModal from './modal/next-tencent-modal';
|
||||
import OllamaModal from './modal/ollama-modal';
|
||||
import SparkModal from './modal/spark-modal';
|
||||
import VolcEngineModal from './modal/volcengine-modal';
|
||||
import YiyanModal from './modal/yiyan-modal';
|
||||
const ModelProviders = () => {
|
||||
const { saveSystemModelSettingLoading, onSystemSettingSavingOk } =
|
||||
useSubmitSystemModelSetting();
|
||||
|
||||
@ -34,11 +34,6 @@ import { CircleHelp } from 'lucide-react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import SettingTitle from '../components/setting-title';
|
||||
import { isLocalLlmFactory } from '../utils';
|
||||
import ApiKeyModal from './api-key-modal';
|
||||
import AzureOpenAIModal from './azure-openai-modal';
|
||||
import BedrockModal from './bedrock-modal';
|
||||
import FishAudioModal from './fish-audio-modal';
|
||||
import GoogleModal from './google-modal';
|
||||
import {
|
||||
useHandleDeleteFactory,
|
||||
useHandleDeleteLlm,
|
||||
@ -55,14 +50,19 @@ import {
|
||||
useSubmitVolcEngine,
|
||||
useSubmityiyan,
|
||||
} from './hooks';
|
||||
import HunyuanModal from './hunyuan-modal';
|
||||
import styles from './index.less';
|
||||
import TencentCloudModal from './next-tencent-modal';
|
||||
import OllamaModal from './ollama-modal';
|
||||
import SparkModal from './spark-modal';
|
||||
import SystemModelSettingModal from './system-model-setting-modal';
|
||||
import VolcEngineModal from './volcengine-modal';
|
||||
import YiyanModal from './yiyan-modal';
|
||||
import ApiKeyModal from './modal/api-key-modal';
|
||||
import AzureOpenAIModal from './modal/azure-openai-modal';
|
||||
import BedrockModal from './modal/bedrock-modal';
|
||||
import FishAudioModal from './modal/fish-audio-modal';
|
||||
import GoogleModal from './modal/google-modal';
|
||||
import HunyuanModal from './modal/hunyuan-modal';
|
||||
import TencentCloudModal from './modal/next-tencent-modal';
|
||||
import OllamaModal from './modal/ollama-modal';
|
||||
import SparkModal from './modal/spark-modal';
|
||||
import SystemModelSettingModal from './modal/system-model-setting-modal';
|
||||
import VolcEngineModal from './modal/volcengine-modal';
|
||||
import YiyanModal from './modal/yiyan-modal';
|
||||
|
||||
const { Text } = Typography;
|
||||
interface IModelCardProps {
|
||||
|
||||
@ -0,0 +1,174 @@
|
||||
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Modal } from '@/components/ui/modal/modal';
|
||||
import { LLMFactory } from '@/constants/llm';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { KeyboardEventHandler, useCallback, useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { ApiKeyPostBody } from '../../../interface';
|
||||
|
||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
loading: boolean;
|
||||
initialValue: string;
|
||||
llmFactory: string;
|
||||
editMode?: boolean;
|
||||
onOk: (postBody: ApiKeyPostBody) => void;
|
||||
showModal?(): void;
|
||||
}
|
||||
|
||||
type FieldType = {
|
||||
api_key?: string;
|
||||
base_url?: string;
|
||||
group_id?: string;
|
||||
};
|
||||
|
||||
const modelsWithBaseUrl = [
|
||||
LLMFactory.OpenAI,
|
||||
LLMFactory.AzureOpenAI,
|
||||
LLMFactory.TongYiQianWen,
|
||||
];
|
||||
|
||||
const ApiKeyModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
llmFactory,
|
||||
loading,
|
||||
initialValue,
|
||||
editMode = false,
|
||||
onOk,
|
||||
}: IProps) => {
|
||||
const form = useForm<FieldType>();
|
||||
const { t } = useTranslate('setting');
|
||||
|
||||
const handleOk = useCallback(async () => {
|
||||
await form.handleSubmit((values) => onOk(values))();
|
||||
}, [form, onOk]);
|
||||
|
||||
const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(
|
||||
async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
await handleOk();
|
||||
}
|
||||
},
|
||||
[handleOk],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
form.setValue('api_key', initialValue);
|
||||
}
|
||||
}, [initialValue, form, visible]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={editMode ? t('editModel') : t('modify')}
|
||||
open={visible}
|
||||
onOpenChange={(open) => !open && hideModal()}
|
||||
onOk={handleOk}
|
||||
onCancel={hideModal}
|
||||
confirmLoading={loading}
|
||||
okText={t('save')}
|
||||
cancelText={t('cancel')}
|
||||
>
|
||||
<Form {...form}>
|
||||
<div className="space-y-4 py-4">
|
||||
<FormField
|
||||
name="api_key"
|
||||
rules={{ required: t('apiKeyMessage') }}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="text-sm font-medium text-text-primary">
|
||||
{t('apiKey')}
|
||||
<span className="ml-1 text-destructive">*</span>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
onKeyDown={handleKeyDown}
|
||||
className="w-full"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{modelsWithBaseUrl.some((x) => x === llmFactory) && (
|
||||
<FormField
|
||||
name="base_url"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="text-sm font-medium text-text-primary">
|
||||
{t('baseUrl')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={
|
||||
llmFactory === LLMFactory.TongYiQianWen
|
||||
? t('tongyiBaseUrlPlaceholder')
|
||||
: 'https://api.openai.com/v1'
|
||||
}
|
||||
onKeyDown={handleKeyDown}
|
||||
className="w-full"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{llmFactory?.toLowerCase() === 'Anthropic'.toLowerCase() && (
|
||||
<FormField
|
||||
name="base_url"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="text-sm font-medium text-text-primary">
|
||||
{t('baseUrl')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder="https://api.anthropic.com/v1"
|
||||
onKeyDown={handleKeyDown}
|
||||
className="w-full"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{llmFactory?.toLowerCase() === 'Minimax'.toLowerCase() && (
|
||||
<FormField
|
||||
name="group_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="text-sm font-medium text-text-primary">
|
||||
Group ID
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} className="w-full" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApiKeyModal;
|
||||
@ -3,7 +3,7 @@ import { IModalProps } from '@/interfaces/common';
|
||||
import { IAddLlmRequestBody } from '@/interfaces/request/llm';
|
||||
import { Flex, Form, Input, InputNumber, Modal, Select, Space } from 'antd';
|
||||
import { useMemo } from 'react';
|
||||
import { BedrockRegionList } from '../constant';
|
||||
import { BedrockRegionList } from '../../constant';
|
||||
|
||||
type FieldType = IAddLlmRequestBody & {
|
||||
bedrock_ak: string;
|
||||
@ -7,7 +7,7 @@ import {
|
||||
} from '@/hooks/llm-hooks';
|
||||
import { Form, Modal, Select } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
import { useFetchSystemModelSettingOnMount } from '../hooks';
|
||||
import { useFetchSystemModelSettingOnMount } from '../../hooks';
|
||||
|
||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
loading: boolean;
|
||||
Reference in New Issue
Block a user