import React, { useEffect, useMemo } from 'react'; import { Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, Box, Typography, CircularProgress, MenuItem, Select, FormControl, InputLabel, FormHelperText, Link, } from '@mui/material'; import { Controller, useForm } from 'react-hook-form'; import logger from '@/utils/logger'; import { LLM_FACTORY_LIST, type LLMFactory } from '@/constants/llm'; // 表单数据接口 export interface OllamaFormData { model_type: string; llm_name: string; api_base: string; api_key?: string; max_tokens: number; llm_factory: string; } // 对话框 Props 接口 export interface OllamaDialogProps { open: boolean; onClose: () => void; onSubmit: (data: OllamaFormData) => void; loading: boolean; initialData?: OllamaFormData; editMode?: boolean; } const llmFactoryToUrlMap: { [x: string]: string } = { [LLM_FACTORY_LIST.Ollama]: 'https://github.com/infiniflow/ragflow/blob/main/docs/guides/models/deploy_local_llm.mdx', [LLM_FACTORY_LIST.Xinference]: 'https://inference.readthedocs.io/en/latest/user_guide', [LLM_FACTORY_LIST.ModelScope]: 'https://www.modelscope.cn/docs/model-service/API-Inference/intro', [LLM_FACTORY_LIST.LocalAI]: 'https://localai.io/docs/getting-started/models/', [LLM_FACTORY_LIST.LMStudio]: 'https://lmstudio.ai/docs/basics', [LLM_FACTORY_LIST.OpenAiAPICompatible]: 'https://platform.openai.com/docs/models/gpt-4', [LLM_FACTORY_LIST.TogetherAI]: 'https://docs.together.ai/docs/deployment-options', [LLM_FACTORY_LIST.Replicate]: 'https://replicate.com/docs/topics/deployments', [LLM_FACTORY_LIST.OpenRouter]: 'https://openrouter.ai/docs', [LLM_FACTORY_LIST.HuggingFace]: 'https://huggingface.co/docs/text-embeddings-inference/quick_tour', [LLM_FACTORY_LIST.GPUStack]: 'https://docs.gpustack.ai/latest/quickstart', [LLM_FACTORY_LIST.VLLM]: 'https://docs.vllm.ai/en/latest/', } as const; function getURLByFactory(factory: LLMFactory) { const url = llmFactoryToUrlMap[factory]; return { textTip: `如何集成 ${factory}`, url, } } // 模型类型选项 const MODEL_TYPE_OPTIONS = [ { value: 'chat', label: 'Chat' }, { value: 'embedding', label: 'Embedding' }, { value: 'rerank', label: 'Rerank' }, { value: 'image2text', label: 'Image2Text' }, { value: 'speech2text', label: 'Speech2Text' }, ]; /** * Ollama / local llm 配置对话框 */ function OllamaDialog({ open, onClose, onSubmit, loading, initialData, editMode = false, }: OllamaDialogProps) { const { control, handleSubmit, formState: { errors }, reset, } = useForm({ defaultValues: { model_type: 'chat', llm_name: '', api_base: initialData?.api_base, api_key: initialData?.api_key, max_tokens: initialData?.max_tokens, llm_factory: initialData?.llm_factory || 'Ollama', }, }); const modelTypeOptions = useMemo(() => { const factory = initialData?.llm_factory || LLM_FACTORY_LIST.Ollama; if (factory == LLM_FACTORY_LIST.HuggingFace) { return [ { value: 'embedding', label: 'Embedding' }, { value: 'chat', label: 'Chat' }, { value: 'rerank', label: 'Rerank' }, ] } else if (factory == LLM_FACTORY_LIST.Xinference) { return [ { value: 'chat', label: 'Chat' }, { value: 'embedding', label: 'Embedding' }, { value: 'rerank', label: 'Rerank' }, { value: 'image2text', label: 'Image2Text' }, { value: 'speech2text', label: 'Speech2Text' }, { value: 'tts', label: 'TTS' }, ] } else if (factory == LLM_FACTORY_LIST.ModelScope) { return [ { value: 'chat', label: 'Chat' }, ] } else if (factory == LLM_FACTORY_LIST.GPUStack) { return [ { value: 'chat', label: 'Chat' }, { value: 'embedding', label: 'Embedding' }, { value: 'rerank', label: 'Rerank' }, { value: 'image2text', label: 'Image2Text' }, ] } return MODEL_TYPE_OPTIONS; }, [initialData]) useEffect(() => { if (open) { reset({ model_type: 'chat', llm_name: '', api_base: initialData?.api_base, api_key: initialData?.api_key, max_tokens: initialData?.max_tokens, llm_factory: initialData?.llm_factory || 'Ollama', }); } }, [open]); const handleFormSubmit = (data: OllamaFormData) => { onSubmit(data); }; // 获取文档链接信息 const docInfo = getURLByFactory((initialData?.llm_factory || LLM_FACTORY_LIST.Ollama) as LLMFactory); return ( {editMode ? `编辑 ${initialData?.llm_factory || LLM_FACTORY_LIST.Ollama}` : `配置 ${initialData?.llm_factory || LLM_FACTORY_LIST.Ollama}`} {/* 模型类型选择 */} ( 模型类型 * {errors.model_type && ( {errors.model_type.message} )} )} /> {/* 模型名称 */} ( )} /> {/* 基础 URL */} ( )} /> {/* API Key (可选) */} ( )} /> {/* 最大 Token 数 */} ( field.onChange(parseInt(e.target.value) || 0)} /> )} /> {/* 左侧文档链接 */} {docInfo.textTip} {/* 右侧按钮组 */} ); }; export default OllamaDialog;