Feat: Search for knowledge-base-level graph nodes. (#17444)

This commit is contained in:
balibabu
2026-07-27 21:03:30 +08:00
committed by GitHub
parent 1ae1dd1edb
commit 1cce9b64f1
98 changed files with 3614 additions and 402 deletions

View File

@@ -223,6 +223,17 @@ export const useNavigatePage = () => {
[navigate],
);
const navigateToCompilationTemplateEditNext = useCallback(
(id?: string) => () => {
if (id && id !== 'create') {
navigate(`${Routes.CompilationTemplatesEditNext}/${id}`);
} else {
navigate(Routes.CompilationTemplatesEditNext);
}
},
[navigate],
);
return {
navigateToDatasetList,
navigateToDataset,
@@ -253,5 +264,6 @@ export const useNavigatePage = () => {
navigateToModelSetting,
navigateToCompilationTemplates,
navigateToCompilationTemplate,
navigateToCompilationTemplateEditNext,
};
};

View File

@@ -139,8 +139,8 @@ export const useFetchAgentListByPage = () => {
const debouncedSearchString = useDebounce(searchString, { wait: 500 });
const { filterValue, handleFilterSubmit } = useHandleFilterSubmit();
const canvasCategory = Array.isArray(filterValue.canvasCategory)
? filterValue.canvasCategory
: [];
? (filterValue.canvasCategory[0] as string | undefined)
: undefined;
const owner = filterValue.owner;
const tags = Array.isArray(filterValue.tags) ? filterValue.tags : undefined;
@@ -148,7 +148,7 @@ export const useFetchAgentListByPage = () => {
page: pagination.current,
pageSize: pagination.pageSize,
keywords: debouncedSearchString,
canvasCategory: canvasCategory.length === 1 ? canvasCategory[0] : undefined,
canvasCategory,
ownerIds: Array.isArray(owner) ? owner : undefined,
tags,
});
@@ -197,7 +197,7 @@ export const useFetchAgentListByPage = () => {
loading,
searchString,
handleInputChange: onInputChange,
pagination: { ...pagination, total: data?.total },
pagination: { ...pagination, total: data?.total ?? 0 },
setPagination,
filterValue,
handleFilterSubmit,

View File

@@ -22,6 +22,7 @@ import {
useGetPaginationWithRouter,
useHandleSearchChange,
} from './logic-hooks';
import { AgentApiAction } from './use-agent-request';
export const enum CompilationTemplateGroupApiAction {
FetchCompilationTemplateGroups = 'fetchCompilationTemplateGroups',
@@ -225,6 +226,10 @@ export const useDeleteCompilationTemplateGroup = () => {
CompilationTemplateGroupApiAction.FetchCompilationTemplateGroups,
],
});
// The agents page lists groups merged into /agents results.
queryClient.invalidateQueries({
queryKey: [AgentApiAction.FetchAgentListByPage],
});
}
return data?.data ?? true;
},

View File

@@ -1,4 +1,5 @@
import message from '@/components/ui/message';
import { CompilationTemplateKind } from '@/constants/compilation';
import {
ICompilationTemplate,
ICompilationTemplateBuiltin,
@@ -52,6 +53,11 @@ export const CompilationTemplateKeys = {
wikiPresets: () => [CompilationTemplateApiAction.FetchWikiPresets] as const,
};
const ExcludedBuiltinKinds: string[] = [
CompilationTemplateKind.SessionEssence,
CompilationTemplateKind.SessionGraph,
];
export const useFetchCompilationTemplatesByPage = () => {
const { searchString, handleInputChange } = useHandleSearchChange();
const { pagination, setPagination } = useGetPaginationWithRouter();
@@ -129,7 +135,9 @@ export const useFetchBuiltinCompilationTemplates = () => {
gcTime: 0,
queryFn: async () => {
const { data } = await listBuiltinCompilationTemplates();
return (data?.data ?? []) as ICompilationTemplateBuiltin[];
return ((data?.data ?? []) as ICompilationTemplateBuiltin[]).filter(
(template) => !ExcludedBuiltinKinds.includes(template.kind),
);
},
},
);

View File

@@ -29,7 +29,12 @@ import kbService, {
} from '@/services/knowledge-service';
import { restAPIv1 } from '@/utils/api';
import { buildChunkHighlights } from '@/utils/document-util';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
keepPreviousData,
useMutation,
useQuery,
useQueryClient,
} from '@tanstack/react-query';
import { useDebounce } from 'ahooks';
import { get } from 'lodash';
import { useCallback, useEffect, useMemo, useState } from 'react';
@@ -83,6 +88,17 @@ export const DocumentStructureKeys = {
datasetId,
documentId,
] as const,
graphWithKeywords: (
datasetId: string,
documentId: string,
keywords: string,
) =>
[
DocumentStructureApiAction.FetchDocumentStructureGraph,
datasetId,
documentId,
keywords,
] as const,
};
export const useUploadDocument = () => {
@@ -718,21 +734,30 @@ export const useFetchDocumentThumbnailsByIds = () => {
return { data, setDocumentIds };
};
export function useFetchDocumentStructureGraph() {
export function useFetchDocumentStructureGraph(keywords?: string) {
const { knowledgeId: datasetId, documentId } = useGetKnowledgeSearchParams();
const enabled = !!datasetId && !!documentId;
const trimmedKeywords = keywords?.trim();
const { data, isFetching: loading } =
useQuery<IStructureGraphResponse | null>({
queryKey: DocumentStructureKeys.graph(datasetId, documentId),
queryKey: trimmedKeywords
? DocumentStructureKeys.graphWithKeywords(
datasetId,
documentId,
trimmedKeywords,
)
: DocumentStructureKeys.graph(datasetId, documentId),
enabled,
initialData: null,
gcTime: 0,
placeholderData: keepPreviousData,
queryFn: async () => {
const { data } =
await documentStructureService.getDocumentStructureGraph(
datasetId,
documentId,
trimmedKeywords,
);
return data?.data ?? null;
},

View File

@@ -2,8 +2,11 @@ import { useHandleFilterSubmit } from '@/components/list-filter-bar/use-handle-f
import message from '@/components/ui/message';
import { ParseType } from '@/constants/knowledge';
import { ResponsePostType, ResponseType } from '@/interfaces/database/base';
import { GenerateType } from '@/pages/dataset/dataset/generate-button/constants';
import { DatasetGenerateKeys } from '@/pages/dataset/dataset/generate-button/hook';
import {
IArtifact,
IArtifactAlteration,
IArtifactGraph,
IArtifactPage,
IArtifactTopic,
@@ -18,6 +21,7 @@ import {
IWikiCommitDetail,
IWikiCommitListResponse,
} from '@/interfaces/database/dataset';
import { type IStructureGraphResponse } from '@/interfaces/database/document-structure';
import {
IFetchArtifactGraphRequestParams,
ITestRetrievalRequestBody,
@@ -27,8 +31,10 @@ import i18n from '@/locales/config';
import kbService, {
clearWiki,
deleteKnowledgeGraph,
getArtifactsAlteration,
getArtifactGraph,
getArtifactPage,
getArtifactsStructure,
getKbDetail,
getKnowledgeGraph,
getWikiCommit,
@@ -40,10 +46,12 @@ import kbService, {
listWikiCommits,
removeTag,
renameTag,
runIndex,
updateArtifactPage,
updateKb,
} from '@/services/knowledge-service';
import {
keepPreviousData,
useInfiniteQuery,
useIsMutating,
useMutation,
@@ -86,6 +94,9 @@ export const enum KnowledgeApiAction {
FetchKnowledgeList = 'fetchKnowledgeList',
RemoveKnowledgeGraph = 'removeKnowledgeGraph',
ClearWiki = 'clearWiki',
FetchDatasetStructure = 'fetchDatasetStructure',
FetchArtifactAlteration = 'fetchArtifactAlteration',
RunArtifactIndex = 'runArtifactIndex',
}
export const useKnowledgeBaseId = (): string => {
@@ -436,6 +447,28 @@ export const ArtifactTopicKeys = {
[KnowledgeApiAction.FetchArtifactTopicList, datasetId] as const,
};
export const ArtifactAlterationKeys = {
detail: (datasetId: string) =>
[KnowledgeApiAction.FetchArtifactAlteration, datasetId] as const,
};
export function useFetchArtifactAlteration() {
const knowledgeBaseId = useKnowledgeBaseId();
const { data, isFetching: loading } = useQuery<IArtifactAlteration | null>({
queryKey: ArtifactAlterationKeys.detail(knowledgeBaseId),
initialData: null,
enabled: !!knowledgeBaseId,
gcTime: 0,
queryFn: async () => {
const { data } = await getArtifactsAlteration(knowledgeBaseId);
return data?.data ?? null;
},
});
return { data, loading };
}
const wikiCommitKeys = {
list: (datasetId: string, pageType: string, slug: string) =>
[KnowledgeApiAction.FetchWikiCommits, datasetId, pageType, slug] as const,
@@ -725,7 +758,13 @@ export function useFetchKnowledgeGraph() {
export const artifactGraphKeys = {
graph: (datasetId: string, params?: IFetchArtifactGraphRequestParams) =>
[KnowledgeApiAction.FetchArtifactGraph, datasetId, params?.node] as const,
[
KnowledgeApiAction.FetchArtifactGraph,
datasetId,
params?.node,
params?.keywords,
params?.top_n,
] as const,
};
export function useFetchArtifactGraph(
@@ -737,6 +776,7 @@ export function useFetchArtifactGraph(
const { data, isFetching: loading } = useQuery<IArtifactGraph>({
queryKey: artifactGraphKeys.graph(knowledgeBaseId, params),
initialData: { entities: [], relations: [] } as IArtifactGraph,
placeholderData: keepPreviousData,
enabled: !!knowledgeBaseId && (options?.enabled ?? true),
gcTime: 0,
queryFn: async () => {
@@ -748,6 +788,51 @@ export function useFetchArtifactGraph(
return { data, loading };
}
export const DatasetStructureKeys = {
all: (datasetId: string) =>
[KnowledgeApiAction.FetchDatasetStructure, datasetId] as const,
kind: (datasetId: string, kind: string) =>
[KnowledgeApiAction.FetchDatasetStructure, datasetId, kind] as const,
kindWithKeywords: (datasetId: string, kind: string, keywords: string) =>
[
KnowledgeApiAction.FetchDatasetStructure,
datasetId,
kind,
keywords,
] as const,
};
export function useFetchDatasetStructureGraph(kind: string, keywords?: string) {
const knowledgeBaseId = useKnowledgeBaseId();
const enabled = !!knowledgeBaseId && !!kind;
const trimmedKeywords = keywords?.trim();
const { data, isFetching: loading } =
useQuery<IStructureGraphResponse | null>({
queryKey: trimmedKeywords
? DatasetStructureKeys.kindWithKeywords(
knowledgeBaseId,
kind,
trimmedKeywords,
)
: DatasetStructureKeys.kind(knowledgeBaseId, kind),
initialData: null,
enabled,
gcTime: 0,
placeholderData: keepPreviousData,
queryFn: async () => {
const { data } = await getArtifactsStructure(
knowledgeBaseId,
kind,
trimmedKeywords,
);
return (data?.data as IStructureGraphResponse | null) ?? null;
},
});
return { data, loading };
}
export function useFetchKnowledgeMetadata(kbIds: string[] = []) {
const { data, isFetching: loading } = useQuery<
Record<string, Record<string, string[]>>
@@ -841,6 +926,43 @@ export const useClearWiki = () => {
return { data, loading, clearWiki: mutateAsync };
};
export const useRunArtifactIndex = () => {
const knowledgeBaseId = useKnowledgeBaseId();
const queryClient = useQueryClient();
const {
data,
isPending: loading,
mutateAsync,
} = useMutation({
mutationKey: [KnowledgeApiAction.RunArtifactIndex],
mutationFn: async () => {
const { data } = await runIndex(knowledgeBaseId, 'artifact');
if (data?.code === 0) {
message.success(i18n.t('message.operated'));
queryClient.invalidateQueries({
queryKey: ArtifactAlterationKeys.detail(knowledgeBaseId),
});
queryClient.invalidateQueries({
queryKey: ArtifactKeys.listByDataset(knowledgeBaseId),
});
queryClient.invalidateQueries({
queryKey: ArtifactTopicKeys.listByDataset(knowledgeBaseId),
});
queryClient.invalidateQueries({
queryKey: DatasetGenerateKeys.traceById(
GenerateType.Artifact,
knowledgeBaseId,
),
});
}
return data;
},
});
return { data, loading, runArtifactIndex: mutateAsync };
};
const KNOWLEDGE_LIST_PAGE_SIZE = 10;
export const KnowledgeListKeys = {