feat(model-settings): add system default model configuration dialog
This commit is contained in:
@@ -40,8 +40,7 @@ export default function AppSvgIcon(props: AppSvgIconProps) {
|
||||
try {
|
||||
setLoading(true);
|
||||
const iconPath = `${svgPath}${pointPath}/${name}.svg?react`;
|
||||
logger.debug(`[AppSvgIcon] 加载图标: ${iconPath}`);
|
||||
|
||||
// logger.debug(`[AppSvgIcon] 加载图标: ${iconPath}`);
|
||||
const iconModule = await import(/* @vite-ignore */ iconPath);
|
||||
setIcon(() => iconModule.default);
|
||||
} catch (error) {
|
||||
|
||||
@@ -310,6 +310,8 @@ export interface ITenantInfo {
|
||||
speech2text_id: string;
|
||||
/** 文本转语音服务ID */
|
||||
tts_id: string;
|
||||
// rerank模型服务ID
|
||||
rerank_id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
@@ -16,9 +16,49 @@ import {
|
||||
CircularProgress,
|
||||
IconButton,
|
||||
InputAdornment,
|
||||
ListSubheader,
|
||||
} from '@mui/material';
|
||||
import { Visibility, VisibilityOff } from '@mui/icons-material';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { LlmSvgIcon } from '@/components/AppSvgIcon';
|
||||
import { IconMap, type LLMFactory } from '@/constants/llm';
|
||||
import type { ITenantInfo } from '@/interfaces/database/knowledge';
|
||||
import type { LlmModelType } from '@/constants/knowledge';
|
||||
import type { IMyLlmModel, IThirdOAIModel } from '@/interfaces/database/llm';
|
||||
|
||||
// 基础对话框状态
|
||||
interface BaseDialogState {
|
||||
open: boolean;
|
||||
loading: boolean;
|
||||
editMode: boolean;
|
||||
closeDialog: () => void;
|
||||
}
|
||||
|
||||
// ModelDialogs 整合组件的 Props 接口
|
||||
interface ModelDialogsProps {
|
||||
apiKeyDialog: BaseDialogState & {
|
||||
initialData: any;
|
||||
factoryName: string;
|
||||
submitApiKey: (data: ApiKeyFormData) => Promise<void>;
|
||||
};
|
||||
azureDialog: BaseDialogState & {
|
||||
initialData: any;
|
||||
submitAzureOpenAI: (data: AzureOpenAIFormData) => Promise<void>;
|
||||
};
|
||||
bedrockDialog: BaseDialogState & {
|
||||
initialData: any;
|
||||
submitBedrock: (data: BedrockFormData) => Promise<void>;
|
||||
};
|
||||
ollamaDialog: BaseDialogState & {
|
||||
initialData: any;
|
||||
submitOllama: (data: OllamaFormData) => Promise<void>;
|
||||
};
|
||||
systemDialog: BaseDialogState & {
|
||||
allModelOptions: any;
|
||||
initialData: Partial<ITenantInfo>;
|
||||
submitSystemModelSetting: (data: Partial<ITenantInfo>) => Promise<void>;
|
||||
};
|
||||
}
|
||||
|
||||
// 接口定义
|
||||
export interface ApiKeyFormData {
|
||||
@@ -53,15 +93,54 @@ const BEDROCK_REGIONS = [
|
||||
'ap-south-1', 'ca-central-1', 'sa-east-1'
|
||||
];
|
||||
|
||||
// 通用 API Key 对话框
|
||||
interface ApiKeyDialogProps {
|
||||
// 基础对话框 Props
|
||||
interface BaseDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (data: ApiKeyFormData) => Promise<void>;
|
||||
loading: boolean;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
// 通用 API Key 对话框
|
||||
interface ApiKeyDialogProps extends BaseDialogProps {
|
||||
onSubmit: (data: ApiKeyFormData) => Promise<void>;
|
||||
factoryName: string;
|
||||
initialData?: Partial<ApiKeyFormData>;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
// Azure OpenAI 对话框
|
||||
interface AzureOpenAIDialogProps extends BaseDialogProps {
|
||||
onSubmit: (data: AzureOpenAIFormData) => Promise<void>;
|
||||
initialData?: Partial<AzureOpenAIFormData>;
|
||||
}
|
||||
|
||||
// AWS Bedrock 对话框
|
||||
interface BedrockDialogProps extends BaseDialogProps {
|
||||
onSubmit: (data: BedrockFormData) => Promise<void>;
|
||||
initialData?: Partial<BedrockFormData>;
|
||||
}
|
||||
|
||||
// Ollama 对话框
|
||||
interface OllamaDialogProps extends BaseDialogProps {
|
||||
onSubmit: (data: OllamaFormData) => Promise<void>;
|
||||
initialData?: Partial<OllamaFormData>;
|
||||
}
|
||||
|
||||
interface AllModelOptionItem {
|
||||
label: string;
|
||||
options: {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled: boolean;
|
||||
model: IThirdOAIModel
|
||||
}[];
|
||||
}
|
||||
|
||||
// 系统默认模型设置对话框
|
||||
interface SystemModelDialogProps extends BaseDialogProps {
|
||||
onSubmit: (data: Partial<ITenantInfo>) => Promise<void>;
|
||||
initialData?: Partial<ITenantInfo>;
|
||||
allModelOptions: Record<string, AllModelOptionItem[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,15 +271,6 @@ export const ApiKeyDialog: React.FC<ApiKeyDialogProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
// Azure OpenAI 对话框
|
||||
interface AzureOpenAIDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (data: AzureOpenAIFormData) => Promise<void>;
|
||||
loading: boolean;
|
||||
initialData?: Partial<AzureOpenAIFormData>;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Azure OpenAI 对话框
|
||||
@@ -348,15 +418,6 @@ export const AzureOpenAIDialog: React.FC<AzureOpenAIDialogProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
// AWS Bedrock 对话框
|
||||
interface BedrockDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (data: BedrockFormData) => Promise<void>;
|
||||
loading: boolean;
|
||||
initialData?: Partial<BedrockFormData>;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* AWS Bedrock 对话框
|
||||
@@ -492,14 +553,6 @@ export const BedrockDialog: React.FC<BedrockDialogProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
interface OllamaDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit: (data: OllamaFormData) => Promise<void>;
|
||||
loading: boolean;
|
||||
initialData?: Partial<OllamaFormData>;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ollama 对话框
|
||||
@@ -598,4 +651,320 @@ export const OllamaDialog: React.FC<OllamaDialogProps> = ({
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 系统默认模型设置对话框
|
||||
*/
|
||||
export const SystemModelDialog: React.FC<SystemModelDialogProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
onSubmit,
|
||||
loading,
|
||||
initialData,
|
||||
allModelOptions
|
||||
}) => {
|
||||
const { control, handleSubmit, reset, formState: { errors } } = useForm<ITenantInfo>({
|
||||
defaultValues: {}
|
||||
});
|
||||
|
||||
// 获取工厂图标名称
|
||||
const getFactoryIconName = (factoryName: LLMFactory) => {
|
||||
return IconMap[factoryName] || 'default';
|
||||
};
|
||||
|
||||
// all model options 包含了全部的 options
|
||||
|
||||
const llmOptions = useMemo(() => allModelOptions?.llmOptions || [], [allModelOptions]);
|
||||
const embdOptions = useMemo(() => allModelOptions?.embeddingOptions || [], [allModelOptions]);
|
||||
const img2txtOptions = useMemo(() => allModelOptions?.image2textOptions || [], [allModelOptions]);
|
||||
const asrOptions = useMemo(() => allModelOptions?.speech2textOptions || [], [allModelOptions]);
|
||||
const ttsOptions = useMemo(() => allModelOptions?.ttsOptions || [], [allModelOptions]);
|
||||
const rerankOptions = useMemo(() => allModelOptions?.rerankOptions || [], [allModelOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open && initialData) {
|
||||
reset(initialData);
|
||||
} else if (open) {
|
||||
reset({
|
||||
llm_id: '',
|
||||
embd_id: '',
|
||||
img2txt_id: '',
|
||||
asr_id: '',
|
||||
tts_id: '',
|
||||
rerank_id: '',
|
||||
});
|
||||
}
|
||||
}, [open, initialData, reset]);
|
||||
|
||||
const handleFormSubmit = async (data: ITenantInfo) => {
|
||||
try {
|
||||
await onSubmit(data);
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>
|
||||
设置默认模型
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Box component="form" sx={{ mt: 2 }}>
|
||||
<Controller
|
||||
name="llm_id"
|
||||
control={control}
|
||||
rules={{ required: '聊天模型是必填项' }}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal" error={!!errors.llm_id}>
|
||||
<InputLabel>聊天模型</InputLabel>
|
||||
<Select {...field} label="聊天模型">
|
||||
{llmOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
{errors.llm_id && (
|
||||
<Typography variant="caption" color="error" sx={{ mt: 1, ml: 2 }}>
|
||||
{errors.llm_id.message}
|
||||
</Typography>
|
||||
)}
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="embd_id"
|
||||
control={control}
|
||||
rules={{ required: '嵌入模型是必填项' }}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal" error={!!errors.embd_id}>
|
||||
<InputLabel>嵌入模型</InputLabel>
|
||||
<Select {...field} label="嵌入模型">
|
||||
{embdOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
{errors.embd_id && (
|
||||
<Typography variant="caption" color="error" sx={{ mt: 1, ml: 2 }}>
|
||||
{errors.embd_id.message}
|
||||
</Typography>
|
||||
)}
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="img2txt_id"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>Img2txt模型</InputLabel>
|
||||
<Select {...field} label="Img2txt模型">
|
||||
{img2txtOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="asr_id"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>Speech2txt模型</InputLabel>
|
||||
<Select {...field} label="Speech2txt模型">
|
||||
{asrOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="rerank_id"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>Rerank模型</InputLabel>
|
||||
<Select {...field} label="Rerank模型">
|
||||
{rerankOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="tts_id"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>TTS模型</InputLabel>
|
||||
<Select {...field} label="TTS模型">
|
||||
{ttsOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
...group.options.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LlmSvgIcon
|
||||
name={getFactoryIconName(group.label as LLMFactory)}
|
||||
sx={{ width: 20, height: 20, color: 'primary.main' }}
|
||||
/>
|
||||
{option.label}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
))
|
||||
])}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} disabled={loading}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSubmit(handleFormSubmit)}
|
||||
variant="contained"
|
||||
disabled={loading}
|
||||
startIcon={loading ? <CircularProgress size={20} /> : null}
|
||||
>
|
||||
确定
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 模型对话框整合组件
|
||||
*/
|
||||
export const ModelDialogs: React.FC<ModelDialogsProps> = ({
|
||||
apiKeyDialog,
|
||||
azureDialog,
|
||||
bedrockDialog,
|
||||
ollamaDialog,
|
||||
systemDialog,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{/* API Key 对话框 */}
|
||||
<ApiKeyDialog
|
||||
open={apiKeyDialog.open}
|
||||
onClose={apiKeyDialog.closeDialog}
|
||||
onSubmit={apiKeyDialog.submitApiKey}
|
||||
loading={apiKeyDialog.loading}
|
||||
factoryName={apiKeyDialog.factoryName}
|
||||
initialData={apiKeyDialog.initialData}
|
||||
editMode={apiKeyDialog!.editMode}
|
||||
/>
|
||||
|
||||
{/* Azure OpenAI 对话框 */}
|
||||
<AzureOpenAIDialog
|
||||
open={azureDialog.open}
|
||||
onClose={azureDialog.closeDialog}
|
||||
onSubmit={azureDialog.submitAzureOpenAI}
|
||||
loading={azureDialog.loading}
|
||||
initialData={azureDialog.initialData}
|
||||
editMode={azureDialog.editMode}
|
||||
/>
|
||||
|
||||
{/* AWS Bedrock 对话框 */}
|
||||
<BedrockDialog
|
||||
open={bedrockDialog.open}
|
||||
onClose={bedrockDialog.closeDialog}
|
||||
onSubmit={bedrockDialog.submitBedrock}
|
||||
loading={bedrockDialog.loading}
|
||||
initialData={bedrockDialog.initialData}
|
||||
editMode={bedrockDialog.editMode}
|
||||
/>
|
||||
|
||||
{/* Ollama 对话框 */}
|
||||
<OllamaDialog
|
||||
open={ollamaDialog.open}
|
||||
onClose={ollamaDialog.closeDialog}
|
||||
onSubmit={ollamaDialog.submitOllama}
|
||||
loading={ollamaDialog.loading}
|
||||
initialData={ollamaDialog.initialData}
|
||||
editMode={ollamaDialog.editMode}
|
||||
/>
|
||||
|
||||
{/* 系统默认模型设置对话框 */}
|
||||
<SystemModelDialog
|
||||
open={systemDialog.open}
|
||||
onClose={systemDialog.closeDialog}
|
||||
onSubmit={systemDialog.submitSystemModelSetting}
|
||||
loading={systemDialog.loading}
|
||||
initialData={systemDialog.initialData}
|
||||
editMode={systemDialog.editMode}
|
||||
allModelOptions={systemDialog.allModelOptions}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,13 +1,16 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
import { useMessage } from '@/hooks/useSnackbar';
|
||||
import userService from '@/services/user_service';
|
||||
import logger from '@/utils/logger';
|
||||
import type {
|
||||
import type {
|
||||
ApiKeyFormData,
|
||||
AzureOpenAIFormData,
|
||||
BedrockFormData,
|
||||
OllamaFormData,
|
||||
} from '../components/ModelDialogs';
|
||||
import type { ITenantInfo } from '@/interfaces/database/knowledge';
|
||||
import { useLlmList } from '@/hooks/llm-hooks';
|
||||
import type { LlmModelType } from '@/constants/knowledge';
|
||||
|
||||
// 对话框状态管理 hook
|
||||
export const useDialogState = () => {
|
||||
@@ -42,7 +45,7 @@ export const useDialogState = () => {
|
||||
// API Key 对话框管理
|
||||
export const useApiKeyDialog = () => {
|
||||
const dialogState = useDialogState();
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
const [factoryName, setFactoryName] = useState('');
|
||||
|
||||
const openApiKeyDialog = useCallback((factory: string, data?: Partial<ApiKeyFormData>, isEdit = false) => {
|
||||
@@ -81,7 +84,7 @@ export const useApiKeyDialog = () => {
|
||||
// Azure OpenAI 对话框管理
|
||||
export const useAzureOpenAIDialog = () => {
|
||||
const dialogState = useDialogState();
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
|
||||
const submitAzureOpenAI = useCallback(async (data: AzureOpenAIFormData) => {
|
||||
dialogState.setLoading(true);
|
||||
@@ -114,7 +117,7 @@ export const useAzureOpenAIDialog = () => {
|
||||
// AWS Bedrock 对话框管理
|
||||
export const useBedrockDialog = () => {
|
||||
const dialogState = useDialogState();
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
|
||||
const submitBedrock = useCallback(async (data: BedrockFormData) => {
|
||||
dialogState.setLoading(true);
|
||||
@@ -148,7 +151,7 @@ export const useBedrockDialog = () => {
|
||||
// Ollama 对话框管理
|
||||
export const useOllamaDialog = () => {
|
||||
const dialogState = useDialogState();
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
|
||||
const submitOllama = useCallback(async (data: OllamaFormData) => {
|
||||
dialogState.setLoading(true);
|
||||
@@ -178,7 +181,7 @@ export const useOllamaDialog = () => {
|
||||
|
||||
// 删除操作管理
|
||||
export const useDeleteOperations = () => {
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const deleteLlm = useCallback(async (factoryName: string, modelName: string) => {
|
||||
@@ -224,9 +227,56 @@ export const useDeleteOperations = () => {
|
||||
// 系统默认模型设置
|
||||
export const useSystemModelSetting = () => {
|
||||
const dialogState = useDialogState();
|
||||
const showMessage = useMessage();
|
||||
const showMessage = useMessage();
|
||||
|
||||
const submitSystemModelSetting = useCallback(async (data: { defaultModel: string }) => {
|
||||
const { data: llmList } = useLlmList();
|
||||
|
||||
const getOptionsByModelType = useCallback((modelType: LlmModelType) => {
|
||||
return Object.entries(llmList)
|
||||
.filter(([, value]) =>
|
||||
modelType
|
||||
? value.some((x) => x.model_type.includes(modelType))
|
||||
: true,
|
||||
)
|
||||
.map(([key, value]) => {
|
||||
return {
|
||||
label: key,
|
||||
options: value
|
||||
.filter(
|
||||
(x) =>
|
||||
(modelType ? x.model_type.includes(modelType) : true) &&
|
||||
x.available,
|
||||
)
|
||||
.map((x) => ({
|
||||
label: x.llm_name,
|
||||
value: `${x.llm_name}@${x.fid}`,
|
||||
disabled: !x.available,
|
||||
model: x,
|
||||
})),
|
||||
};
|
||||
})
|
||||
.filter((x) => x.options.length > 0);
|
||||
}, [llmList]);
|
||||
|
||||
const allModelOptions = useMemo(() => {
|
||||
const llmOptions = getOptionsByModelType('chat');
|
||||
const image2textOptions = getOptionsByModelType('image2text');
|
||||
const embeddingOptions = getOptionsByModelType('embedding');
|
||||
const speech2textOptions = getOptionsByModelType('speech2text');
|
||||
const rerankOptions = getOptionsByModelType('rerank');
|
||||
const ttsOptions = getOptionsByModelType('tts');
|
||||
|
||||
return {
|
||||
llmOptions,
|
||||
image2textOptions,
|
||||
embeddingOptions,
|
||||
speech2textOptions,
|
||||
rerankOptions,
|
||||
ttsOptions,
|
||||
}
|
||||
}, [llmList, getOptionsByModelType]);
|
||||
|
||||
const submitSystemModelSetting = useCallback(async (data: Partial<ITenantInfo>) => {
|
||||
dialogState.setLoading(true);
|
||||
try {
|
||||
// 这里需要根据实际的 API 接口调整
|
||||
@@ -245,6 +295,7 @@ export const useSystemModelSetting = () => {
|
||||
return {
|
||||
...dialogState,
|
||||
submitSystemModelSetting,
|
||||
allModelOptions,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import AppSvgIcon, { LlmSvgIcon } from '@/components/AppSvgIcon';
|
||||
import { LLM_FACTORY_LIST, IconMap, type LLMFactory } from '@/constants/llm';
|
||||
import type { IFactory, IMyLlmModel, ILlmItem } from '@/interfaces/database/llm';
|
||||
import LLMFactoryCard, { MODEL_TYPE_COLORS } from './components/LLMFactoryCard';
|
||||
import { ModelDialogs } from './components/ModelDialogs';
|
||||
|
||||
|
||||
// 主页面组件
|
||||
@@ -90,13 +91,25 @@ function ModelsPage() {
|
||||
|
||||
return (
|
||||
<Box sx={{ p: 3 }}>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
模型设置
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" gutterBottom>
|
||||
管理您的 LLM 模型工厂和个人模型配置
|
||||
</Typography>
|
||||
|
||||
<Box mb={4} sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}>
|
||||
<Box>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
模型设置
|
||||
</Typography>
|
||||
<Typography variant="body1" color="text.secondary" gutterBottom>
|
||||
管理您的 LLM 模型工厂和个人模型配置
|
||||
</Typography>
|
||||
</Box>
|
||||
{/* 设置默认模型 */}
|
||||
<Button variant="contained" color="primary" onClick={() => modelDialogs.systemDialog.openDialog()}>
|
||||
设置默认模型
|
||||
</Button>
|
||||
</Box>
|
||||
{/* My LLM 部分 */}
|
||||
<Box mb={4} mt={2}>
|
||||
{!myLlm || Object.keys(myLlm).length === 0 ? (
|
||||
@@ -197,13 +210,12 @@ function ModelsPage() {
|
||||
<Typography variant="h5" gutterBottom>
|
||||
LLM 模型工厂
|
||||
</Typography>
|
||||
<AppSvgIcon name='arxiv' />
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container spacing={2}>
|
||||
{
|
||||
llmFactory.map((factory) => (
|
||||
<Grid size={{ xs: 6, sm: 4, md: 3 }} key={factory.name}>
|
||||
<Grid size={{ xs: 6, sm: 4, md: 3 }} key={factory.name}>
|
||||
<LLMFactoryCard
|
||||
key={factory.name}
|
||||
factory={factory}
|
||||
@@ -218,7 +230,7 @@ function ModelsPage() {
|
||||
</Box>
|
||||
|
||||
{/* 模型配置对话框 */}
|
||||
{/* <ModelDialogs {...modelDialogs} /> */}
|
||||
<ModelDialogs {...modelDialogs} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user