feat(form): add form field components and configuration updates

refactor(knowledge): restructure configuration components to use common items
This commit is contained in:
2025-10-15 18:48:48 +08:00
parent fe8747983e
commit fd4309582d
36 changed files with 1869 additions and 1001 deletions

View File

@@ -1,49 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function AudioConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,60 +1,60 @@
import React from 'react';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import {
ChunkMethodItem,
EmbeddingModelItem,
LayoutRecognizeItem,
PageRankItem,
AutoKeywordsItem,
AutoQuestionsItem,
UseRaptorItem,
RaptorPromptItem,
RaptorMaxTokenItem,
RaptorThresholdItem,
RaptorMaxClusterItem,
RaptorRandomSeedItem,
UseGraphragItem,
EntityTypesItem,
GraphragMethodItem,
EntityNormalizeItem,
CommunityReportItem,
TagsItem
} from './common-items';
export function BookConfiguration() {
return (
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<LayoutRecognizeItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<PageRankItem />
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<AutoKeywordsItem />
<AutoQuestionsItem />
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
<UseRaptorItem />
<RaptorPromptItem />
<RaptorMaxTokenItem />
<RaptorThresholdItem />
<RaptorMaxClusterItem />
<RaptorRandomSeedItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2, p: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<ConfigurationFormContainer>
<UseGraphragItem />
<EntityTypesItem />
<GraphragMethodItem />
<EntityNormalizeItem />
<CommunityReportItem />
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<TagsItem />
</ConfigurationFormContainer>
</MainContainer>
);

View File

@@ -1,118 +0,0 @@
import {
FormControl,
InputLabel,
Select,
MenuItem,
FormHelperText,
Box,
Typography,
ListSubheader,
} from '@mui/material';
import { useFormContext, Controller } from 'react-hook-form';
import { DOCUMENT_PARSER_TYPES } from '@/constants/knowledge';
import { useSelectChunkMethodList } from '../hooks';
import { useEmbeddingModelOptions } from '@/hooks/llm-hooks';
// 解析器选项配置
const PARSER_OPTIONS = [
{ value: DOCUMENT_PARSER_TYPES.Naive, label: 'General', description: '通用解析器' },
{ value: DOCUMENT_PARSER_TYPES.Qa, label: 'Q&A', description: 'Q&A解析器' },
{ value: DOCUMENT_PARSER_TYPES.Resume, label: 'Resume', description: 'Resume解析器' },
{ value: DOCUMENT_PARSER_TYPES.Manual, label: 'Manual', description: 'Manual解析器' },
{ value: DOCUMENT_PARSER_TYPES.Table, label: 'Table', description: 'Table解析器' },
{ value: DOCUMENT_PARSER_TYPES.Paper, label: 'Paper', description: 'Paper解析器' },
{ value: DOCUMENT_PARSER_TYPES.Book, label: 'Book', description: 'Book解析器' },
{ value: DOCUMENT_PARSER_TYPES.Laws, label: 'Laws', description: 'Laws解析器' },
{ value: DOCUMENT_PARSER_TYPES.Presentation, label: 'Presentation', description: 'Presentation解析器' },
{ value: DOCUMENT_PARSER_TYPES.One, label: 'One', description: 'One解析器' },
{ value: DOCUMENT_PARSER_TYPES.Tag, label: 'Tag', description: 'Tag解析器' },
];
export function ChunkMethodItem() {
const { control, formState: { errors } } = useFormContext();
const parserIds = useSelectChunkMethodList();
const parserOptions = parserIds.map((x) => ({
value: x,
label: PARSER_OPTIONS.find((y) => y.value === x)?.label || x,
description: PARSER_OPTIONS.find((y) => y.value === x)?.description || x,
}));
return (
<Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="parser_id"
control={control}
render={({ field }) => (
<FormControl fullWidth error={!!errors.parser_id}>
<InputLabel></InputLabel>
<Select
{...field}
label="选择切片方法"
>
{parserOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
<Box>
<Typography variant="body1">{option.label}</Typography>
<Typography variant="caption" color="text.secondary">
{option.description}
</Typography>
</Box>
</MenuItem>
))}
</Select>
{errors.parser_id && (
<FormHelperText>{errors.parser_id.message as string}</FormHelperText>
)}
</FormControl>
)}
/>
</Box>
);
}
export function EmbeddingModelItem() {
const { control, formState: { errors } } = useFormContext();
const { options: embdOptions } = useEmbeddingModelOptions();
return (
<Box sx={{ mb: 3 }}>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="embd_id"
control={control}
render={({ field }) => (
<FormControl fullWidth error={!!errors.embd_id}>
<InputLabel></InputLabel>
<Select
{...field}
label="选择嵌入模型"
>
{
embdOptions.map((group) => [
<ListSubheader key={`header-${group.label}`} disableSticky>
{group.label}
</ListSubheader>,
...group.options.map((option) => (
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
{option.label}
</MenuItem>
))
])
}
</Select>
{errors.embd_id && (
<FormHelperText>{errors.embd_id.message as string}</FormHelperText>
)}
</FormControl>
)}
/>
</Box>
);
}

View File

@@ -0,0 +1,416 @@
import { useMemo } from 'react';
import {
FormControl,
InputLabel,
Select,
MenuItem,
FormHelperText,
Box,
Typography,
ListSubheader,
Button,
} from '@mui/material';
import { Shuffle as ShuffleIcon } from '@mui/icons-material';
import { useFormContext, Controller } from 'react-hook-form';
import { DOCUMENT_PARSER_TYPES, LLM_MODEL_TYPES, type LlmModelType } from '@/constants/knowledge';
import { useSelectChunkMethodList } from '../hooks';
import { useEmbeddingModelOptions, useLlmOptionsByModelType } from '@/hooks/llm-hooks';
import {
SliderInputFormField,
SwitchFormField,
SelectFormField,
MultilineTextFormField,
NumberInputFormField,
ChipListFormField,
TextFormField,
type SelectOption,
} from '@/components/FormField';
// 解析器选项配置
const PARSER_OPTIONS = [
{ value: DOCUMENT_PARSER_TYPES.Naive, label: 'General', description: '通用解析器' },
{ value: DOCUMENT_PARSER_TYPES.Qa, label: 'Q&A', description: 'Q&A解析器' },
{ value: DOCUMENT_PARSER_TYPES.Resume, label: 'Resume', description: 'Resume解析器' },
{ value: DOCUMENT_PARSER_TYPES.Manual, label: 'Manual', description: 'Manual解析器' },
{ value: DOCUMENT_PARSER_TYPES.Table, label: 'Table', description: 'Table解析器' },
{ value: DOCUMENT_PARSER_TYPES.Paper, label: 'Paper', description: 'Paper解析器' },
{ value: DOCUMENT_PARSER_TYPES.Book, label: 'Book', description: 'Book解析器' },
{ value: DOCUMENT_PARSER_TYPES.Laws, label: 'Laws', description: 'Laws解析器' },
{ value: DOCUMENT_PARSER_TYPES.Presentation, label: 'Presentation', description: 'Presentation解析器' },
{ value: DOCUMENT_PARSER_TYPES.One, label: 'One', description: 'One解析器' },
{ value: DOCUMENT_PARSER_TYPES.Tag, label: 'Tag', description: 'Tag解析器' },
];
export function ChunkMethodItem() {
const { control, formState: { errors } } = useFormContext();
const parserIds = useSelectChunkMethodList();
const parserOptions = parserIds.map((x) => ({
value: x,
label: PARSER_OPTIONS.find((y) => y.value === x)?.label || x,
description: PARSER_OPTIONS.find((y) => y.value === x)?.description || x,
}));
return (
<Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="parser_id"
control={control}
render={({ field }) => (
<FormControl fullWidth error={!!errors.parser_id}>
<InputLabel></InputLabel>
<Select
{...field}
label="选择切片方法"
>
{parserOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
<Box>
<Typography variant="body1">{option.label}</Typography>
<Typography variant="caption" color="text.secondary">
{option.description}
</Typography>
</Box>
</MenuItem>
))}
</Select>
{errors.parser_id && (
<FormHelperText>{errors.parser_id.message as string}</FormHelperText>
)}
</FormControl>
)}
/>
</Box>
);
}
// 基于基础FormField组件的业务组合组件
// 分块token数量配置
export function ChunkTokenNumberItem() {
return (
<SliderInputFormField
name="parser_config.chunk_token_num"
label="建议文本块大小"
min={64}
max={2048}
step={64}
defaultValue={512}
layout="horizontal"
/>
);
}
// 页面排名配置
export function PageRankItem() {
return (
<NumberInputFormField
name="parser_config.page_rank"
label="页面排名"
defaultValue={0}
min={0}
placeholder="输入页面排名"
/>
);
}
// 自动关键词数量配置
export function AutoKeywordsItem() {
return (
<NumberInputFormField
name="parser_config.auto_keywords"
label="自动关键词"
defaultValue={0}
min={0}
placeholder="输入关键词数量"
/>
);
}
// 自动问题数量配置
export function AutoQuestionsItem() {
return (
<NumberInputFormField
name="parser_config.auto_questions"
label="自动问题"
defaultValue={0}
min={0}
placeholder="输入问题数量"
/>
);
}
// 表格转HTML开关
export function HtmlForExcelItem() {
return (
<SwitchFormField
name="parser_config.html4excel"
label="表格转HTML"
defaultValue={false}
/>
);
}
// 标签集选择
export function TagsItem() {
const tagsOptions: SelectOption[] = [
{ value: '', label: '请选择' },
// 这里可以根据实际需求添加标签选项
];
return (
<SelectFormField
name="parser_config.tags"
label="标签集"
options={tagsOptions}
defaultValue=""
displayEmpty
/>
);
}
// RAPTOR策略开关
export function UseRaptorItem() {
return (
<SwitchFormField
name="parser_config.raptor.use_raptor"
label="使用召回增强RAPTOR策略"
defaultValue={false}
/>
);
}
// RAPTOR提示词配置
export function RaptorPromptItem() {
return (
<MultilineTextFormField
name="parser_config.raptor.prompt"
label="提示词"
defaultValue="请总结以下段落。小心数字,不要编造。段落如下:\n{cluster_content}\n以上就是你需要总结的内容。"
rows={4}
/>
);
}
// RAPTOR最大token数配置
export function RaptorMaxTokenItem() {
return (
<SliderInputFormField
name="parser_config.raptor.max_token"
label="最大token数"
min={64}
max={512}
step={32}
defaultValue={256}
layout="horizontal"
/>
);
}
// RAPTOR阈值配置
export function RaptorThresholdItem() {
return (
<SliderInputFormField
name="parser_config.raptor.threshold"
label="阈值"
min={0}
max={1}
step={0.1}
defaultValue={0.1}
layout="horizontal"
/>
);
}
// RAPTOR最大聚类数配置
export function RaptorMaxClusterItem() {
return (
<SliderInputFormField
name="parser_config.raptor.max_cluster"
label="最大聚类数"
min={16}
max={128}
step={16}
defaultValue={64}
layout="horizontal"
/>
);
}
// RAPTOR随机种子配置
export function RaptorRandomSeedItem() {
return (
<NumberInputFormField
name="parser_config.raptor.random_seed"
label="随机种子"
defaultValue={0}
showRandomButton
/>
);
}
// 知识图谱开关
export function UseGraphragItem() {
return (
<SwitchFormField
name="parser_config.graphrag.use_graphrag"
label="提取知识图谱"
defaultValue={false}
/>
);
}
// 实体类型配置
export function EntityTypesItem() {
return (
<ChipListFormField
name="parser_config.graphrag.entity_types"
label="*实体类型"
defaultValue={['organization', 'person', 'geo', 'event', 'category']}
required
allowAdd
allowDelete
maxChips={10}
/>
);
}
// GraphRAG方法选择
export function GraphragMethodItem() {
const methodOptions: SelectOption[] = [
{ value: 'Light', label: 'Light' },
{ value: 'General', label: 'General' },
];
return (
<SelectFormField
name="parser_config.graphrag.method"
label="方法"
options={methodOptions}
defaultValue="Light"
displayEmpty={false}
/>
);
}
// 实体归一化开关
export function EntityNormalizeItem() {
return (
<SwitchFormField
name="parser_config.graphrag.entity_normalize"
label="实体归一化"
defaultValue={false}
/>
);
}
// 社区报告生成开关
export function CommunityReportItem() {
return (
<SwitchFormField
name="parser_config.graphrag.community_report"
label="社区报告生成"
defaultValue={false}
/>
);
}
export function EmbeddingModelItem() {
const { control } = useFormContext();
const { options } = useEmbeddingModelOptions();
return (
<Box>
<Typography variant="subtitle1" sx={{ minWidth: 120 }}>
</Typography>
<Box sx={{ flex: 1 }}>
<Controller
name="embd_id"
control={control}
render={({ field }) => (
<FormControl fullWidth variant="outlined">
<Select
{...field}
>
{options.map((group) => [
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
...group.options.map((option) => (
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
{option.label}
</MenuItem>
))
])}
</Select>
</FormControl>
)}
/>
</Box>
</Box>
);
}
// PDF解析器配置
export function LayoutRecognizeItem() {
const { control, setValue, formState } = useFormContext();
const { getOptionsByModelType } = useLlmOptionsByModelType();
const options = useMemo(() => {
// 基础选项
const basicOptions = [
{ value: 'DeepDOC', label: 'DeepDOC' },
{ value: 'Plain Text', label: '纯文本' }
];
// 获取图像转文本模型选项
const image2TextOptions = getOptionsByModelType(LLM_MODEL_TYPES.Image2text);
// 将图像转文本模型选项转换为SelectOption格式
const image2TextSelectOptions = image2TextOptions.flatMap(group =>
group.options.map(option => ({
value: option.value,
label: `${option.label} (实验性)`
}))
);
return [...basicOptions, ...image2TextSelectOptions];
}, [getOptionsByModelType]);
return (
<Controller
name="parser_config.layout_recognize"
control={control}
render={({ field }) => {
// 设置默认值
if (typeof field.value === 'undefined') {
const defaultValue = formState.defaultValues?.parser_config?.layout_recognize ?? 'DeepDOC';
setValue('parser_config.layout_recognize', defaultValue);
}
return (
<SelectFormField
name="parser_config.layout_recognize"
label="PDF解析器"
options={options}
defaultValue="DeepDOC"
/>
);
}}
/>
);
}
// 文本分段标识符配置
export function DelimiterItem() {
return (
<TextFormField
name="parser_config.delimiter"
label="分隔符"
placeholder="请输入分隔符"
defaultValue="\n!?。;!?"
/>
);
}

View File

@@ -1,49 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function EmailConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -2,7 +2,7 @@
export { NaiveConfiguration } from './naive';
export { QAConfiguration } from './qa';
export { PaperConfiguration } from './paper';
export { ChunkMethodItem, EmbeddingModelItem } from './common-item';
export { ChunkMethodItem, EmbeddingModelItem } from './common-items';
export { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
// 所有解析器配置组件

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { ChunkMethodItem, EmbeddingModelItem } from './common-items';
import { Box, Typography } from '@mui/material';
export function KnowledgeGraphConfiguration() {

View File

@@ -1,61 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function LawsConfiguration() {
return (
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
</ConfigurationFormContainer>
</MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,59 +1,67 @@
import React from 'react';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import {
ChunkMethodItem,
EmbeddingModelItem,
ChunkTokenNumberItem,
DelimiterItem,
LayoutRecognizeItem,
PageRankItem,
AutoKeywordsItem,
AutoQuestionsItem,
HtmlForExcelItem,
UseRaptorItem,
RaptorPromptItem,
RaptorMaxTokenItem,
RaptorThresholdItem,
RaptorMaxClusterItem,
RaptorRandomSeedItem,
UseGraphragItem,
EntityTypesItem,
GraphragMethodItem,
EntityNormalizeItem,
CommunityReportItem,
TagsItem
} from './common-items';
export function ManualConfiguration() {
return (
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<ChunkTokenNumberItem />
<DelimiterItem />
<LayoutRecognizeItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<HtmlForExcelItem />
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
<UseRaptorItem />
<RaptorPromptItem />
<RaptorMaxTokenItem />
<RaptorThresholdItem />
<RaptorMaxClusterItem />
<RaptorRandomSeedItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<ConfigurationFormContainer>
<UseGraphragItem />
<EntityTypesItem />
<GraphragMethodItem />
<EntityNormalizeItem />
<CommunityReportItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<ConfigurationFormContainer>
<TagsItem />
</ConfigurationFormContainer>
</MainContainer>
);
}

View File

@@ -2,27 +2,39 @@ import React from 'react';
import {
Box,
Typography,
FormControl,
InputLabel,
Select,
MenuItem,
TextField,
FormControlLabel,
Switch,
Slider,
Accordion,
AccordionSummary,
AccordionDetails,
Chip,
IconButton,
} from '@mui/material';
import { ExpandMore as ExpandMoreIcon, Add as AddIcon } from '@mui/icons-material';
import { useFormContext, Controller } from 'react-hook-form';
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
import { useFormContext } from 'react-hook-form';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import {
ChunkMethodItem,
EmbeddingModelItem,
ChunkTokenNumberItem,
PageRankItem,
AutoKeywordsItem,
AutoQuestionsItem,
HtmlForExcelItem,
TagsItem,
UseRaptorItem,
RaptorPromptItem,
RaptorMaxTokenItem,
RaptorThresholdItem,
RaptorMaxClusterItem,
RaptorRandomSeedItem,
UseGraphragItem,
EntityTypesItem,
GraphragMethodItem,
EntityNormalizeItem,
CommunityReportItem,
LayoutRecognizeItem,
DelimiterItem
} from './common-items';
export function NaiveConfiguration() {
const { control, watch, formState: { errors } } = useFormContext();
const { formState: { errors } } = useFormContext();
return (
<ConfigurationFormContainer>
@@ -38,72 +50,16 @@ export function NaiveConfiguration() {
<ChunkMethodItem />
{/* PDF解析器 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
PDF解析器
</Typography>
<Controller
name="parser_config.pdf_parser"
control={control}
render={({ field }) => (
<FormControl fullWidth>
<Select
{...field}
displayEmpty
defaultValue="Naive"
>
<MenuItem value="Naive">Naive</MenuItem>
</Select>
</FormControl>
)}
/>
</Box>
<LayoutRecognizeItem />
{/* 嵌入模型 */}
<EmbeddingModelItem />
{/* 建议文本块大小 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.chunk_token_num"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={128}
max={2048}
step={64}
valueLabelDisplay="on"
defaultValue={512}
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<ChunkTokenNumberItem />
{/* 文本分段标识符 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
*
</Typography>
<Controller
name="parser_config.delimiter"
control={control}
render={({ field }) => (
<TextField
{...field}
fullWidth
placeholder="\\n"
defaultValue="\\n"
/>
)}
/>
</Box>
<DelimiterItem />
</Box>
</AccordionDetails>
</Accordion>
@@ -116,250 +72,47 @@ export function NaiveConfiguration() {
<AccordionDetails>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
{/* 页面排名 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.page_rank"
control={control}
render={({ field }) => (
<TextField
{...field}
type="number"
fullWidth
defaultValue={0}
inputProps={{ min: 0 }}
/>
)}
/>
</Box>
<PageRankItem />
{/* 自动关键词提取 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.auto_keywords"
control={control}
render={({ field }) => (
<TextField
{...field}
type="number"
fullWidth
defaultValue={0}
inputProps={{ min: 0 }}
/>
)}
/>
</Box>
<AutoKeywordsItem />
{/* 自动问题提取 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.auto_questions"
control={control}
render={({ field }) => (
<TextField
{...field}
type="number"
fullWidth
defaultValue={0}
inputProps={{ min: 0 }}
/>
)}
/>
</Box>
<AutoQuestionsItem />
{/* 表格转HTML */}
<Box>
<Controller
name="parser_config.html4excel"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Switch
checked={field.value || false}
onChange={field.onChange}
/>
}
label="表格转HTML"
/>
)}
/>
</Box>
<HtmlForExcelItem />
{/* 标签集 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.tags"
control={control}
render={({ field }) => (
<FormControl fullWidth>
<Select
{...field}
displayEmpty
defaultValue=""
>
<MenuItem value=""></MenuItem>
</Select>
</FormControl>
)}
/>
</Box>
<TagsItem />
</Box>
</AccordionDetails>
</Accordion>
{/* 第三部分RAPTOR策略 */}
<Accordion defaultExpanded>
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="h6">RAPTOR策略</Typography>
</AccordionSummary>
<AccordionDetails>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
{/* 使用召回增强RAPTOR策略 */}
<Box>
<Controller
name="parser_config.raptor.use_raptor"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Switch
checked={field.value || false}
onChange={field.onChange}
/>
}
label="使用召回增强RAPTOR策略"
/>
)}
/>
</Box>
<UseRaptorItem />
{/* 提示词 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.raptor.prompt"
control={control}
render={({ field }) => (
<TextField
{...field}
multiline
rows={4}
fullWidth
defaultValue="请总结以下段落。小心数字,不要编造。段落如下:\n{cluster_content}\n以上就是你需要总结的内容。"
/>
)}
/>
</Box>
<RaptorPromptItem />
{/* 最大token数 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
token数
</Typography>
<Controller
name="parser_config.raptor.max_token"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={64}
max={512}
step={32}
valueLabelDisplay="on"
defaultValue={256}
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<RaptorMaxTokenItem />
{/* 阈值 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.raptor.threshold"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={0}
max={1}
step={0.1}
valueLabelDisplay="on"
defaultValue={0.1}
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<RaptorThresholdItem />
{/* 最大聚类数 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.raptor.max_cluster"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={16}
max={128}
step={16}
valueLabelDisplay="on"
defaultValue={64}
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<RaptorMaxClusterItem />
{/* 随机种子 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.raptor.random_seed"
control={control}
render={({ field }) => (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<TextField
{...field}
type="number"
defaultValue={0}
sx={{ flex: 1 }}
/>
<IconButton>
<AddIcon />
</IconButton>
</Box>
)}
/>
</Box>
<RaptorRandomSeedItem />
</Box>
</AccordionDetails>
</Accordion>
@@ -372,109 +125,19 @@ export function NaiveConfiguration() {
<AccordionDetails>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
{/* 提取知识图谱 */}
<Box>
<Controller
name="parser_config.graphrag.use_graphrag"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Switch
checked={field.value || false}
onChange={field.onChange}
/>
}
label="提取知识图谱"
/>
)}
/>
</Box>
<UseGraphragItem />
{/* 实体类型 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
*
</Typography>
<Controller
name="parser_config.graphrag.entity_types"
control={control}
render={({ field }) => (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2 }}>
{['organization', 'person', 'geo', 'event', 'category'].map((type) => (
<Chip
key={type}
label={type}
onDelete={() => {}}
variant="outlined"
/>
))}
<IconButton size="small">
<AddIcon />
</IconButton>
</Box>
)}
/>
</Box>
<EntityTypesItem />
{/* 方法 */}
<Box>
<Typography variant="subtitle1" gutterBottom>
</Typography>
<Controller
name="parser_config.graphrag.method"
control={control}
render={({ field }) => (
<FormControl fullWidth>
<Select
{...field}
defaultValue="Light"
>
<MenuItem value="Light">Light</MenuItem>
<MenuItem value="General">General</MenuItem>
</Select>
</FormControl>
)}
/>
</Box>
<GraphragMethodItem />
{/* 实体归一化 */}
<Box>
<Controller
name="parser_config.graphrag.entity_normalize"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Switch
checked={field.value || false}
onChange={field.onChange}
/>
}
label="实体归一化"
/>
)}
/>
</Box>
<EntityNormalizeItem />
{/* 社区报告生成 */}
<Box>
<Controller
name="parser_config.graphrag.community_report"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Switch
checked={field.value || false}
onChange={field.onChange}
/>
}
label="社区报告生成"
/>
)}
/>
</Box>
<CommunityReportItem />
</Box>
</AccordionDetails>
</Accordion>

View File

@@ -1,48 +1,67 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import {
ChunkMethodItem,
EmbeddingModelItem,
ChunkTokenNumberItem,
DelimiterItem,
LayoutRecognizeItem,
PageRankItem,
AutoKeywordsItem,
AutoQuestionsItem,
HtmlForExcelItem,
UseRaptorItem,
RaptorPromptItem,
RaptorMaxTokenItem,
RaptorThresholdItem,
RaptorMaxClusterItem,
RaptorRandomSeedItem,
UseGraphragItem,
EntityTypesItem,
GraphragMethodItem,
EntityNormalizeItem,
CommunityReportItem,
TagsItem
} from './common-items';
export function OneConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<EmbeddingModelItem />
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<ChunkTokenNumberItem />
<DelimiterItem />
<LayoutRecognizeItem />
<EmbeddingModelItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<ConfigurationFormContainer>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<HtmlForExcelItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<ConfigurationFormContainer>
<UseRaptorItem />
<RaptorPromptItem />
<RaptorMaxTokenItem />
<RaptorThresholdItem />
<RaptorMaxClusterItem />
<RaptorRandomSeedItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<ConfigurationFormContainer>
<UseGraphragItem />
<EntityTypesItem />
<GraphragMethodItem />
<EntityNormalizeItem />
<CommunityReportItem />
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<TagsItem />
</ConfigurationFormContainer>
</MainContainer>
);
}

View File

@@ -1,121 +1,61 @@
import React from 'react';
import {
Box,
Typography,
FormControl,
InputLabel,
Select,
MenuItem,
TextField,
Slider,
} from '@mui/material';
import { useFormContext, Controller } from 'react-hook-form';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import {
ChunkMethodItem,
EmbeddingModelItem,
LayoutRecognizeItem,
PageRankItem,
AutoKeywordsItem,
AutoQuestionsItem,
UseRaptorItem,
RaptorPromptItem,
RaptorMaxTokenItem,
RaptorThresholdItem,
RaptorMaxClusterItem,
RaptorRandomSeedItem,
UseGraphragItem,
EntityTypesItem,
GraphragMethodItem,
EntityNormalizeItem,
CommunityReportItem,
TagsItem
} from './common-items';
export function PaperConfiguration() {
const { control } = useFormContext();
return (
<ConfigurationFormContainer>
<MainContainer>
{/* 布局识别 */}
<Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="parser_config.layout_recognize"
control={control}
render={({ field }) => (
<FormControl fullWidth>
<InputLabel></InputLabel>
<Select
{...field}
label="布局识别方式"
>
<MenuItem value="DeepDOC">DeepDOC</MenuItem>
<MenuItem value="Plain Text">Plain Text</MenuItem>
</Select>
</FormControl>
)}
/>
</Box>
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<LayoutRecognizeItem />
<EmbeddingModelItem />
<PageRankItem />
</ConfigurationFormContainer>
{/* 自动关键词 */}
<Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="parser_config.auto_keywords"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={0}
max={10}
step={1}
marks
valueLabelDisplay="auto"
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<ConfigurationFormContainer>
<AutoKeywordsItem />
<AutoQuestionsItem />
</ConfigurationFormContainer>
{/* 自动问题 */}
<Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Controller
name="parser_config.auto_questions"
control={control}
render={({ field }) => (
<Box sx={{ px: 2 }}>
<Slider
{...field}
min={0}
max={10}
step={1}
marks
valueLabelDisplay="auto"
onChange={(_, value) => field.onChange(value)}
/>
</Box>
)}
/>
</Box>
<ConfigurationFormContainer>
<UseRaptorItem />
<RaptorPromptItem />
<RaptorMaxTokenItem />
<RaptorThresholdItem />
<RaptorMaxClusterItem />
<RaptorRandomSeedItem />
</ConfigurationFormContainer>
{/* 标签数量 */}
<Box>
<Typography variant="h6" gutterBottom>
Top N
</Typography>
<Controller
name="parser_config.topn_tags"
control={control}
render={({ field }) => (
<TextField
{...field}
type="number"
fullWidth
label="标签数量"
inputProps={{ min: 1, max: 10 }}
onChange={(e) => field.onChange(parseInt(e.target.value))}
/>
)}
/>
</Box>
<ConfigurationFormContainer>
<UseGraphragItem />
<EntityTypesItem />
<GraphragMethodItem />
<EntityNormalizeItem />
<CommunityReportItem />
</ConfigurationFormContainer>
<Box>
<Typography variant="body2" color="text.secondary">
</Typography>
</Box>
</MainContainer>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<TagsItem />
</ConfigurationFormContainer>
</MainContainer>
);
}

View File

@@ -1,37 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function PictureConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,61 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function PresentationConfiguration() {
return (
<MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
</ConfigurationFormContainer>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
Raptor配置 -
</Typography>
</Box>
</ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
GraphRAG配置 -
</Typography>
</Box>
<ConfigurationFormContainer>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
</ConfigurationFormContainer>
</MainContainer>
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,45 +1,14 @@
import React from 'react';
import {
Box,
Typography,
TextField,
} from '@mui/material';
import { useFormContext, Controller } from 'react-hook-form';
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, TagsItem } from './common-items';
export function QAConfiguration() {
const { control } = useFormContext();
return (
<ConfigurationFormContainer>
<MainContainer>
{/* 标签数量 */}
<Box>
<Typography variant="h6" gutterBottom>
Top N
</Typography>
<Controller
name="parser_config.topn_tags"
control={control}
render={({ field }) => (
<TextField
{...field}
type="number"
fullWidth
label="标签数量"
inputProps={{ min: 1, max: 10 }}
onChange={(e) => field.onChange(parseInt(e.target.value))}
/>
)}
/>
</Box>
<Box>
<Typography variant="body2" color="text.secondary">
Q&A解析器专门用于处理问答格式的文档
</Typography>
</Box>
</MainContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<PageRankItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,25 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function ResumeConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
-
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,19 +1,16 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { Box, Typography } from '@mui/material';
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
export function TableConfiguration() {
return (
<ConfigurationFormContainer>
<ChunkMethodItem />
<EmbeddingModelItem />
<Box sx={{ mb: 2 }}>
<Typography variant="body2" color="text.secondary">
PageRank配置 -
</Typography>
</Box>
<PageRankItem />
<AutoKeywordsItem />
<AutoQuestionsItem />
<TagsItem />
</ConfigurationFormContainer>
);
}

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { ConfigurationFormContainer } from './configuration-form-container';
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
import { ChunkMethodItem, EmbeddingModelItem } from './common-items';
import { Box, Typography } from '@mui/material';
export function TagConfiguration() {

View File

@@ -71,6 +71,7 @@ function KnowledgeBaseSetting() {
permission: knowledge.permission || 'me',
avatar: knowledge.avatar,
parser_id: knowledge.parser_id || DOCUMENT_PARSER_TYPES.Naive,
embd_id: knowledge.embd_id || '',
parser_config: {
chunk_token_num: knowledge.parser_config?.chunk_token_num || 512,
delimiter: knowledge.parser_config?.delimiter || '\n',