feat(knowledge): add configuration components and refactor general form
feat(hooks): add llm-related hooks and constants docs: add architecture analysis for reference projects
This commit is contained in:
@@ -17,6 +17,7 @@ export interface UseDocumentListState {
|
||||
// 文档列表Hook返回值接口
|
||||
export interface UseDocumentListReturn extends UseDocumentListState {
|
||||
fetchDocuments: (params?: IFetchKnowledgeListRequestParams) => Promise<void>;
|
||||
fetchDocumentsFilter: () => Promise<void>;
|
||||
setKeywords: (keywords: string) => void;
|
||||
setCurrentPage: (page: number) => void;
|
||||
setPageSize: (size: number) => void;
|
||||
@@ -95,6 +96,27 @@ export const useDocumentList = (
|
||||
}
|
||||
}, [kbId, keywords, currentPage, pageSize]);
|
||||
|
||||
/**
|
||||
* 获取文档过滤器
|
||||
*/
|
||||
const fetchDocumentsFilter = useCallback(async () => {
|
||||
if (!kbId) return;
|
||||
|
||||
try {
|
||||
const response = await knowledgeService.getDocumentFilter({
|
||||
kb_id: kbId,
|
||||
});
|
||||
if (response.data.code === 0) {
|
||||
const data = response.data.data;
|
||||
} else {
|
||||
throw new Error(response.data.message || '获取文档过滤器失败');
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = error.response?.data?.message || error.message || '获取文档过滤器失败';
|
||||
console.error('Failed to fetch document filter:', error);
|
||||
}
|
||||
}, [kbId, keywords]);
|
||||
|
||||
/**
|
||||
* 刷新当前页面数据
|
||||
*/
|
||||
@@ -139,6 +161,7 @@ export const useDocumentList = (
|
||||
pageSize,
|
||||
keywords,
|
||||
fetchDocuments,
|
||||
fetchDocumentsFilter,
|
||||
setKeywords: handleSetKeywords,
|
||||
setCurrentPage: handleSetCurrentPage,
|
||||
setPageSize: handleSetPageSize,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import knowledgeService from '@/services/knowledge_service';
|
||||
import type { IKnowledge, IKnowledgeResult } from '@/interfaces/database/knowledge';
|
||||
import type { IKnowledge, IKnowledgeResult, IParserConfig } from '@/interfaces/database/knowledge';
|
||||
import type { IFetchKnowledgeListRequestParams } from '@/interfaces/request/knowledge';
|
||||
|
||||
/**
|
||||
@@ -299,11 +299,9 @@ export const useKnowledgeOperations = () => {
|
||||
* 包括嵌入模型、解析器配置、相似度阈值等
|
||||
*/
|
||||
const updateKnowledgeModelConfig = useCallback(async (data: {
|
||||
id: string;
|
||||
kb_id: string;
|
||||
embd_id?: string;
|
||||
// parser_config?: Partial<ParserConfig>;
|
||||
similarity_threshold?: number;
|
||||
vector_similarity_weight?: number;
|
||||
parser_config?: Partial<IParserConfig>;
|
||||
parser_id?: string;
|
||||
}) => {
|
||||
try {
|
||||
@@ -311,7 +309,6 @@ export const useKnowledgeOperations = () => {
|
||||
setError(null);
|
||||
|
||||
const updateData = {
|
||||
kb_id: data.id,
|
||||
...data,
|
||||
};
|
||||
|
||||
|
||||
195
src/hooks/llm-hooks.ts
Normal file
195
src/hooks/llm-hooks.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { LLM_MODEL_TYPES, type LlmModelType } from "@/constants/knowledge";
|
||||
import type { IThirdOAIModelCollection, IThirdOAIModel } from "@/interfaces/database/llm";
|
||||
import userService from "@/services/user_service";
|
||||
|
||||
/**
|
||||
* 获取LLM模型列表的Hook
|
||||
* @param modelType 可选的模型类型过滤
|
||||
* @returns LLM模型数据和相关状态
|
||||
*/
|
||||
export function useLlmList(modelType?: LlmModelType) {
|
||||
const [data, setData] = useState<IThirdOAIModelCollection>({});
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchLlmList = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const response = await userService.llm_list({ model_type: modelType });
|
||||
|
||||
if (response.data?.code === 0) {
|
||||
setData(response.data?.data ?? {});
|
||||
} else {
|
||||
setError(response.data?.message || '获取LLM列表失败');
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : '获取LLM列表失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [modelType]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchLlmList();
|
||||
}, [fetchLlmList]);
|
||||
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
refresh: fetchLlmList,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用的LLM选项列表
|
||||
* @param modelType 可选的模型类型过滤
|
||||
* @returns 格式化的选项列表
|
||||
*/
|
||||
export function useLlmOptions(modelType?: LlmModelType) {
|
||||
const { data: llmInfo, loading, error } = useLlmList(modelType);
|
||||
|
||||
const options = useMemo(() => {
|
||||
return Object.entries(llmInfo).map(([key, value]) => {
|
||||
return {
|
||||
label: key,
|
||||
options: value
|
||||
.filter((x) => x.available) // 只显示可用的模型
|
||||
.map((x) => ({
|
||||
label: x.llm_name,
|
||||
value: `${x.llm_name}@${x.fid}`,
|
||||
disabled: !x.available,
|
||||
model: x,
|
||||
})),
|
||||
};
|
||||
}).filter((group) => group.options.length > 0); // 过滤掉空组
|
||||
}, [llmInfo]);
|
||||
|
||||
return {
|
||||
options,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模型类型获取分组的LLM选项
|
||||
* @returns 按模型类型分组的选项
|
||||
*/
|
||||
export function useLlmOptionsByModelType() {
|
||||
const { data: llmInfo, loading, error } = useLlmList();
|
||||
|
||||
const getOptionsByModelType = useCallback((modelType: LlmModelType) => {
|
||||
return Object.entries(llmInfo)
|
||||
.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);
|
||||
}, [llmInfo]);
|
||||
|
||||
return {
|
||||
getOptionsByModelType,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取嵌入模型选项
|
||||
* @returns 嵌入模型选项列表
|
||||
*/
|
||||
export function useEmbeddingModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.Embedding);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取聊天模型选项
|
||||
* @returns 聊天模型选项列表
|
||||
*/
|
||||
export function useChatModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.Chat);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取重排序模型选项
|
||||
* @returns 重排序模型选项列表
|
||||
*/
|
||||
export function useRerankModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.Rerank);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图像转文本模型选项
|
||||
* @returns 图像转文本模型选项列表
|
||||
*/
|
||||
export function useImage2TextModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.Image2text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取语音转文本模型选项
|
||||
* @returns 语音转文本模型选项列表
|
||||
*/
|
||||
export function useSpeech2TextModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.Speech2text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本转语音模型选项
|
||||
* @returns 文本转语音模型选项列表
|
||||
*/
|
||||
export function useTTSModelOptions() {
|
||||
return useLlmOptions(LLM_MODEL_TYPES.TTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模型ID获取模型详情
|
||||
* @param modelId 模型ID (格式: llm_name@fid)
|
||||
* @returns 模型详情
|
||||
*/
|
||||
export function useLlmModelDetail(modelId?: string) {
|
||||
const { data: llmInfo, loading, error } = useLlmList();
|
||||
|
||||
const modelDetail = useMemo(() => {
|
||||
if (!modelId || !llmInfo) return null;
|
||||
|
||||
const [llmName, fid] = modelId.split('@');
|
||||
|
||||
for (const models of Object.values(llmInfo)) {
|
||||
const model = models.find(
|
||||
(m) => m.llm_name === llmName && m.fid === fid
|
||||
);
|
||||
if (model) return model;
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [modelId, llmInfo]);
|
||||
|
||||
return {
|
||||
modelDetail,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user