2025-04-27 14:39:05 +08:00
|
|
|
import { useHandleFilterSubmit } from '@/components/list-filter-bar/use-handle-filter-submit';
|
2025-08-28 14:45:20 +08:00
|
|
|
import message from '@/components/ui/message';
|
2026-04-10 19:05:14 +08:00
|
|
|
import { ParseType } from '@/constants/knowledge';
|
2025-12-02 17:24:29 +08:00
|
|
|
import { ResponsePostType } from '@/interfaces/database/base';
|
2025-04-22 15:01:35 +08:00
|
|
|
import {
|
2026-04-29 14:37:48 +08:00
|
|
|
IDataset,
|
|
|
|
|
IDatasetListResult,
|
2025-07-21 19:11:27 +08:00
|
|
|
IKnowledgeGraph,
|
2025-04-22 15:01:35 +08:00
|
|
|
INextTestingResult,
|
2025-12-02 17:24:29 +08:00
|
|
|
IRenameTag,
|
|
|
|
|
ITestingResult,
|
2026-04-29 14:37:48 +08:00
|
|
|
} from '@/interfaces/database/dataset';
|
2025-04-17 19:03:55 +08:00
|
|
|
import { ITestRetrievalRequestBody } from '@/interfaces/request/knowledge';
|
2025-04-22 15:01:35 +08:00
|
|
|
import i18n from '@/locales/config';
|
2025-07-21 19:11:27 +08:00
|
|
|
import kbService, {
|
2025-09-28 12:18:58 +08:00
|
|
|
deleteKnowledgeGraph,
|
feat(api): add unified index API and dataset management endpoints (#14222)
### What problem does this PR solve?
## Summary
Refactor the dataset API layer into a clean service/REST separation
pattern, add a unified `/index` API for graph/raptor/mindmap operations,
and introduce several new dataset management endpoints with full test
coverage.
## Changes
### Service Layer (`dataset_api_service.py`)
- Added `trace_index(dataset_id, tenant_id, index_type)` — unified trace
function for all index types
- Added `run_index`, `delete_index` service functions
- Added `get_dataset`, `get_ingestion_summary`, `list_ingestion_logs`,
`get_ingestion_log`
- Added `run_embedding`, `list_tags`, `aggregate_tags`, `delete_tags`,
`rename_tag`
- Added `get_flattened_metadata`, `get_auto_metadata`,
`update_auto_metadata`
### REST API Layer (`dataset_api.py`)
**New unified routes:**
| Method | Route | Description |
|--------|-------|-------------|
| POST | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Run index
task |
| GET | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Trace index
task |
| DELETE | `/datasets/<id>/<index_type>` | Delete index |
| GET | `/datasets/<id>` | Get dataset details |
| GET | `/datasets/<id>/ingestions/summary` | Ingestion summary |
| GET | `/datasets/<id>/ingestions` | List ingestion logs |
| GET | `/datasets/<id>/ingestions/<log_id>` | Get single ingestion log
|
| POST | `/datasets/<id>/embedding` | Run embedding |
| GET | `/datasets/<id>/tags` | List tags |
| GET | `/datasets/tags/aggregation` | Aggregate tags across datasets |
| DELETE | `/datasets/<id>/tags` | Delete tags |
| PUT | `/datasets/<id>/tags` | Rename tag |
| GET | `/datasets/metadata/flattened` | Get flattened metadata |
| GET/PUT | `/datasets/<id>/metadata/config` | New metadata config path
|
**Removed routes (replaced by unified `/index`):**
- `POST /datasets/<id>/mindmap`
- `GET /datasets/<id>/mindmap`
**Preserved legacy routes (backward compatibility):**
- `/run_graphrag`, `/trace_graphrag`, `/run_raptor`, `/trace_raptor`
- `/auto_metadata` GET/PUT
### Test Suite
- Updated `common.py` helpers: added `trace_index`, removed
`run_mindmap`/`trace_mindmap`
- Added 7 new test files with 39 test cases total:
| Test File | Cases |
|-----------|-------|
| `test_get_dataset.py` | 4 |
| `test_ingestion_summary.py` | 2 |
| `test_ingestion_logs.py` | 5 |
| `test_index_api.py` | 14 |
| `test_embedding.py` | 2 |
| `test_tags.py` | 8 |
| `test_flattened_metadata.py` | 4 |
- Deleted `test_mindmap_tasks.py` (covered by unified index tests)
## Design Decisions
1. **Unified `/index?type=...`** — single endpoint replaces 3 separate
route pairs for graph/raptor/mindmap
2. **Backward compatibility** — old routes (`/run_graphrag`,
`/run_raptor`, `/auto_metadata`) preserved alongside new paths
3. **`_VALID_INDEX_TYPES = {"graph", "raptor", "mindmap"}`** — input
validation via constant set
4. **`_INDEX_TYPE_TO_TASK_ID_FIELD`** — maps index type to KB model task
ID field for clean dispatch
## Files Changed
- `api/apps/restful_apis/dataset_api.py`
- `api/apps/services/dataset_api_service.py`
- `sdk/python/ragflow_sdk/modules/dataset.py`
- `test/testcases/test_http_api/common.py`
- `test/testcases/test_http_api/test_dataset_management/` (7 new files)
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- [x] Refactoring
---------
Signed-off-by: noob <yixiao121314@outlook.com>
2026-04-27 01:38:01 +00:00
|
|
|
getKbDetail,
|
2025-07-21 19:11:27 +08:00
|
|
|
getKnowledgeGraph,
|
|
|
|
|
listDataset,
|
2025-12-02 17:24:29 +08:00
|
|
|
listTag,
|
|
|
|
|
removeTag,
|
|
|
|
|
renameTag,
|
2026-03-19 14:41:36 +08:00
|
|
|
updateKb,
|
2025-07-21 19:11:27 +08:00
|
|
|
} from '@/services/knowledge-service';
|
2025-12-02 17:24:29 +08:00
|
|
|
import {
|
|
|
|
|
useIsMutating,
|
|
|
|
|
useMutation,
|
|
|
|
|
useMutationState,
|
|
|
|
|
useQuery,
|
|
|
|
|
useQueryClient,
|
|
|
|
|
} from '@tanstack/react-query';
|
2025-04-22 15:01:35 +08:00
|
|
|
import { useDebounce } from 'ahooks';
|
2026-03-20 15:46:41 +08:00
|
|
|
import { omit } from 'lodash';
|
|
|
|
|
import { useCallback, useMemo, useState } from 'react';
|
2026-01-04 19:14:20 +08:00
|
|
|
import { useParams, useSearchParams } from 'react-router';
|
2025-04-22 15:01:35 +08:00
|
|
|
import {
|
|
|
|
|
useGetPaginationWithRouter,
|
|
|
|
|
useHandleSearchChange,
|
|
|
|
|
} from './logic-hooks';
|
2026-04-27 23:42:57 +08:00
|
|
|
import { extractParserConfigExt } from './parser-config-utils';
|
2025-12-02 17:24:29 +08:00
|
|
|
import { useSetPaginationParams } from './route-hook';
|
2025-04-17 19:03:55 +08:00
|
|
|
|
|
|
|
|
export const enum KnowledgeApiAction {
|
2025-04-22 15:01:35 +08:00
|
|
|
FetchKnowledgeListByPage = 'fetchKnowledgeListByPage',
|
|
|
|
|
CreateKnowledge = 'createKnowledge',
|
|
|
|
|
DeleteKnowledge = 'deleteKnowledge',
|
|
|
|
|
SaveKnowledge = 'saveKnowledge',
|
2025-04-25 11:15:44 +08:00
|
|
|
FetchKnowledgeDetail = 'fetchKnowledgeDetail',
|
2025-08-12 10:15:10 +08:00
|
|
|
FetchKnowledgeGraph = 'fetchKnowledgeGraph',
|
|
|
|
|
FetchMetadata = 'fetchMetadata',
|
2026-04-30 18:13:27 +03:00
|
|
|
FetchMetadataKeys = 'fetchMetadataKeys',
|
2025-10-09 12:36:19 +08:00
|
|
|
FetchKnowledgeList = 'fetchKnowledgeList',
|
2025-09-28 12:18:58 +08:00
|
|
|
RemoveKnowledgeGraph = 'removeKnowledgeGraph',
|
2025-04-17 19:03:55 +08:00
|
|
|
}
|
|
|
|
|
|
2025-07-21 19:11:27 +08:00
|
|
|
export const useKnowledgeBaseId = (): string => {
|
2025-04-17 19:03:55 +08:00
|
|
|
const { id } = useParams();
|
|
|
|
|
|
2025-07-21 19:11:27 +08:00
|
|
|
return (id as string) || '';
|
2025-04-17 19:03:55 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useTestRetrieval = () => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
const [values, setValues] = useState<ITestRetrievalRequestBody>();
|
2026-03-20 15:46:41 +08:00
|
|
|
const { filterValue, setFilterValue } = useHandleFilterSubmit();
|
2025-05-16 18:56:48 +08:00
|
|
|
|
2025-04-17 19:03:55 +08:00
|
|
|
const queryParams = useMemo(() => {
|
|
|
|
|
return {
|
|
|
|
|
...values,
|
|
|
|
|
kb_id: values?.kb_id || knowledgeBaseId,
|
2026-06-11 16:36:05 +08:00
|
|
|
page: 1,
|
2025-05-16 18:56:48 +08:00
|
|
|
doc_ids: filterValue.doc_ids,
|
2025-12-12 17:12:38 +08:00
|
|
|
highlight: true,
|
2025-04-17 19:03:55 +08:00
|
|
|
};
|
2026-06-11 16:36:05 +08:00
|
|
|
}, [filterValue, knowledgeBaseId, values]);
|
2025-04-17 19:03:55 +08:00
|
|
|
|
2026-03-20 15:46:41 +08:00
|
|
|
const mutation = useMutation<INextTestingResult, Error, typeof queryParams>({
|
|
|
|
|
mutationFn: async (params) => {
|
2026-04-13 21:07:07 +08:00
|
|
|
const { data } = await kbService.retrievalTest(params);
|
2025-09-08 12:49:12 +08:00
|
|
|
const result = data?.data ?? {};
|
|
|
|
|
return { ...result, isRuned: true };
|
2025-04-17 19:03:55 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-20 15:46:41 +08:00
|
|
|
const refetch = useCallback(() => {
|
|
|
|
|
if (queryParams.question) {
|
2026-06-10 19:11:31 +08:00
|
|
|
const newParams = { ...queryParams, page: 1 };
|
|
|
|
|
mutation.mutate(newParams);
|
2025-05-16 18:56:48 +08:00
|
|
|
}
|
2026-03-20 15:46:41 +08:00
|
|
|
}, [mutation, queryParams]);
|
|
|
|
|
|
|
|
|
|
const handleFilterSubmit = useCallback(
|
|
|
|
|
(value: { doc_ids?: string[] }) => {
|
|
|
|
|
setFilterValue(value);
|
|
|
|
|
if (mutation.data && queryParams.question) {
|
|
|
|
|
const newParams = {
|
|
|
|
|
...queryParams,
|
|
|
|
|
doc_ids: value.doc_ids ?? [],
|
|
|
|
|
page: 1,
|
|
|
|
|
};
|
|
|
|
|
mutation.mutate(newParams);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[mutation, queryParams, setFilterValue],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const data = useMemo(
|
|
|
|
|
() =>
|
|
|
|
|
mutation.data ?? {
|
|
|
|
|
chunks: [],
|
|
|
|
|
doc_aggs: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
isRuned: false,
|
|
|
|
|
},
|
|
|
|
|
[mutation.data],
|
|
|
|
|
);
|
2025-05-16 18:56:48 +08:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
data,
|
2026-03-20 15:46:41 +08:00
|
|
|
loading: mutation.isPending,
|
2025-05-16 18:56:48 +08:00
|
|
|
setValues,
|
|
|
|
|
refetch,
|
|
|
|
|
handleFilterSubmit,
|
2025-05-19 19:34:43 +08:00
|
|
|
filterValue,
|
2025-05-16 18:56:48 +08:00
|
|
|
};
|
2025-04-17 19:03:55 +08:00
|
|
|
};
|
2025-04-22 15:01:35 +08:00
|
|
|
|
|
|
|
|
export const useFetchNextKnowledgeListByPage = () => {
|
|
|
|
|
const { searchString, handleInputChange } = useHandleSearchChange();
|
|
|
|
|
const { pagination, setPagination } = useGetPaginationWithRouter();
|
|
|
|
|
const debouncedSearchString = useDebounce(searchString, { wait: 500 });
|
2025-04-27 14:39:05 +08:00
|
|
|
const { filterValue, handleFilterSubmit } = useHandleFilterSubmit();
|
2025-04-22 15:01:35 +08:00
|
|
|
|
2026-04-14 18:07:32 +08:00
|
|
|
const { data, isFetching: loading } = useQuery<IDatasetListResult>({
|
2025-04-22 15:01:35 +08:00
|
|
|
queryKey: [
|
|
|
|
|
KnowledgeApiAction.FetchKnowledgeListByPage,
|
|
|
|
|
{
|
|
|
|
|
debouncedSearchString,
|
|
|
|
|
...pagination,
|
2025-04-27 14:39:05 +08:00
|
|
|
filterValue,
|
2025-04-22 15:01:35 +08:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
initialData: {
|
|
|
|
|
kbs: [],
|
2026-03-19 14:41:36 +08:00
|
|
|
total_datasets: 0,
|
2025-04-22 15:01:35 +08:00
|
|
|
},
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
queryFn: async () => {
|
2026-03-19 14:41:36 +08:00
|
|
|
const { data } = await listDataset({
|
|
|
|
|
page_size: pagination.pageSize,
|
|
|
|
|
page: pagination.current,
|
|
|
|
|
ext: {
|
2025-04-22 15:01:35 +08:00
|
|
|
keywords: debouncedSearchString,
|
2026-03-20 15:46:41 +08:00
|
|
|
owner_ids: filterValue.owner as string[],
|
2025-04-22 15:01:35 +08:00
|
|
|
},
|
2026-03-19 14:41:36 +08:00
|
|
|
});
|
2025-04-22 15:01:35 +08:00
|
|
|
|
2026-03-19 14:41:36 +08:00
|
|
|
return { kbs: data?.data, total_datasets: data?.total_datasets };
|
2025-04-22 15:01:35 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onInputChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(
|
|
|
|
|
(e) => {
|
2025-10-09 13:55:36 +08:00
|
|
|
// setPagination({ page: 1 }); // TODO: This results in repeated requests
|
2025-04-22 15:01:35 +08:00
|
|
|
handleInputChange(e);
|
|
|
|
|
},
|
|
|
|
|
[handleInputChange],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...data,
|
|
|
|
|
searchString,
|
|
|
|
|
handleInputChange: onInputChange,
|
2026-03-19 14:41:36 +08:00
|
|
|
pagination: { ...pagination, total: data?.total_datasets },
|
2025-04-22 15:01:35 +08:00
|
|
|
setPagination,
|
|
|
|
|
loading,
|
2025-04-27 14:39:05 +08:00
|
|
|
filterValue,
|
|
|
|
|
handleFilterSubmit,
|
2025-04-22 15:01:35 +08:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useCreateKnowledge = () => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: [KnowledgeApiAction.CreateKnowledge],
|
2026-03-19 14:41:36 +08:00
|
|
|
mutationFn: async (params: {
|
|
|
|
|
id?: string;
|
|
|
|
|
name: string;
|
|
|
|
|
embedding_model?: string;
|
|
|
|
|
chunk_method?: string;
|
2026-04-10 19:05:14 +08:00
|
|
|
parseType?: ParseType;
|
2026-03-19 14:41:36 +08:00
|
|
|
pipeline_id?: string | null;
|
|
|
|
|
ext?: {
|
|
|
|
|
language?: string;
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
};
|
|
|
|
|
}) => {
|
2025-04-22 15:01:35 +08:00
|
|
|
const { data = {} } = await kbService.createKb(params);
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(
|
|
|
|
|
i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
|
|
|
|
|
);
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] });
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, createKnowledge: mutateAsync };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useDeleteKnowledge = () => {
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: [KnowledgeApiAction.DeleteKnowledge],
|
|
|
|
|
mutationFn: async (id: string) => {
|
2026-03-19 14:41:36 +08:00
|
|
|
const { data } = await kbService.rmKb({ ids: [id] });
|
2025-04-22 15:01:35 +08:00
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(i18n.t(`message.deleted`));
|
|
|
|
|
queryClient.invalidateQueries({
|
|
|
|
|
queryKey: [KnowledgeApiAction.FetchKnowledgeListByPage],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data?.data ?? [];
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, deleteKnowledge: mutateAsync };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useUpdateKnowledge = (shouldFetchList = false) => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
const queryClient = useQueryClient();
|
2026-03-19 14:41:36 +08:00
|
|
|
|
2025-04-22 15:01:35 +08:00
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: [KnowledgeApiAction.SaveKnowledge],
|
2026-03-19 14:41:36 +08:00
|
|
|
mutationFn: async (params: {
|
|
|
|
|
kb_id?: string;
|
|
|
|
|
name?: string;
|
|
|
|
|
embedding_model?: string;
|
|
|
|
|
chunk_method?: string;
|
|
|
|
|
pipeline_id?: string | null;
|
|
|
|
|
avatar?: string | null;
|
|
|
|
|
description?: string;
|
|
|
|
|
permission?: string;
|
|
|
|
|
pagerank?: number;
|
|
|
|
|
parser_config?: Record<string, any>;
|
|
|
|
|
[key: string]: any;
|
|
|
|
|
}) => {
|
|
|
|
|
const kbId = params?.kb_id || knowledgeBaseId;
|
|
|
|
|
const {
|
|
|
|
|
embedding_model,
|
|
|
|
|
chunk_method,
|
|
|
|
|
pipeline_id,
|
|
|
|
|
avatar,
|
|
|
|
|
description,
|
|
|
|
|
permission,
|
|
|
|
|
pagerank,
|
|
|
|
|
parser_config,
|
|
|
|
|
...ext
|
|
|
|
|
} = params;
|
|
|
|
|
const requestBody: Record<string, any> = {
|
|
|
|
|
name,
|
|
|
|
|
embedding_model,
|
|
|
|
|
chunk_method,
|
|
|
|
|
pipeline_id,
|
|
|
|
|
avatar,
|
|
|
|
|
description,
|
|
|
|
|
permission,
|
|
|
|
|
pagerank,
|
|
|
|
|
parser_config: extractParserConfigExt(parser_config),
|
2026-03-20 15:46:41 +08:00
|
|
|
...omit(ext, ['kb_id']),
|
2026-03-19 14:41:36 +08:00
|
|
|
};
|
2026-04-27 23:42:57 +08:00
|
|
|
|
2026-03-19 14:41:36 +08:00
|
|
|
const { data = {} } = await updateKb(kbId, requestBody);
|
2025-04-22 15:01:35 +08:00
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(i18n.t(`message.updated`));
|
|
|
|
|
if (shouldFetchList) {
|
|
|
|
|
queryClient.invalidateQueries({
|
|
|
|
|
queryKey: [KnowledgeApiAction.FetchKnowledgeListByPage],
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, saveKnowledgeConfiguration: mutateAsync };
|
|
|
|
|
};
|
2025-04-25 11:15:44 +08:00
|
|
|
|
2025-10-09 12:36:19 +08:00
|
|
|
export const useFetchKnowledgeBaseConfiguration = (props?: {
|
|
|
|
|
isEdit?: boolean;
|
|
|
|
|
}) => {
|
2026-04-14 18:07:32 +08:00
|
|
|
const { isEdit = true } = props || { isEdit: true };
|
2025-04-25 11:15:44 +08:00
|
|
|
const { id } = useParams();
|
2025-07-15 16:12:50 +08:00
|
|
|
const [searchParams] = useSearchParams();
|
|
|
|
|
const knowledgeBaseId = searchParams.get('id') || id;
|
2025-04-25 11:15:44 +08:00
|
|
|
|
2026-04-29 14:37:48 +08:00
|
|
|
const { data, isFetching: loading } = useQuery<IDataset>({
|
2026-04-14 18:07:32 +08:00
|
|
|
queryKey: [KnowledgeApiAction.FetchKnowledgeDetail, knowledgeBaseId],
|
2026-04-29 14:37:48 +08:00
|
|
|
initialData: {} as IDataset,
|
2025-04-25 11:15:44 +08:00
|
|
|
gcTime: 0,
|
2026-04-14 18:07:32 +08:00
|
|
|
enabled: !!knowledgeBaseId && isEdit,
|
2025-04-25 11:15:44 +08:00
|
|
|
queryFn: async () => {
|
feat(api): add unified index API and dataset management endpoints (#14222)
### What problem does this PR solve?
## Summary
Refactor the dataset API layer into a clean service/REST separation
pattern, add a unified `/index` API for graph/raptor/mindmap operations,
and introduce several new dataset management endpoints with full test
coverage.
## Changes
### Service Layer (`dataset_api_service.py`)
- Added `trace_index(dataset_id, tenant_id, index_type)` — unified trace
function for all index types
- Added `run_index`, `delete_index` service functions
- Added `get_dataset`, `get_ingestion_summary`, `list_ingestion_logs`,
`get_ingestion_log`
- Added `run_embedding`, `list_tags`, `aggregate_tags`, `delete_tags`,
`rename_tag`
- Added `get_flattened_metadata`, `get_auto_metadata`,
`update_auto_metadata`
### REST API Layer (`dataset_api.py`)
**New unified routes:**
| Method | Route | Description |
|--------|-------|-------------|
| POST | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Run index
task |
| GET | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Trace index
task |
| DELETE | `/datasets/<id>/<index_type>` | Delete index |
| GET | `/datasets/<id>` | Get dataset details |
| GET | `/datasets/<id>/ingestions/summary` | Ingestion summary |
| GET | `/datasets/<id>/ingestions` | List ingestion logs |
| GET | `/datasets/<id>/ingestions/<log_id>` | Get single ingestion log
|
| POST | `/datasets/<id>/embedding` | Run embedding |
| GET | `/datasets/<id>/tags` | List tags |
| GET | `/datasets/tags/aggregation` | Aggregate tags across datasets |
| DELETE | `/datasets/<id>/tags` | Delete tags |
| PUT | `/datasets/<id>/tags` | Rename tag |
| GET | `/datasets/metadata/flattened` | Get flattened metadata |
| GET/PUT | `/datasets/<id>/metadata/config` | New metadata config path
|
**Removed routes (replaced by unified `/index`):**
- `POST /datasets/<id>/mindmap`
- `GET /datasets/<id>/mindmap`
**Preserved legacy routes (backward compatibility):**
- `/run_graphrag`, `/trace_graphrag`, `/run_raptor`, `/trace_raptor`
- `/auto_metadata` GET/PUT
### Test Suite
- Updated `common.py` helpers: added `trace_index`, removed
`run_mindmap`/`trace_mindmap`
- Added 7 new test files with 39 test cases total:
| Test File | Cases |
|-----------|-------|
| `test_get_dataset.py` | 4 |
| `test_ingestion_summary.py` | 2 |
| `test_ingestion_logs.py` | 5 |
| `test_index_api.py` | 14 |
| `test_embedding.py` | 2 |
| `test_tags.py` | 8 |
| `test_flattened_metadata.py` | 4 |
- Deleted `test_mindmap_tasks.py` (covered by unified index tests)
## Design Decisions
1. **Unified `/index?type=...`** — single endpoint replaces 3 separate
route pairs for graph/raptor/mindmap
2. **Backward compatibility** — old routes (`/run_graphrag`,
`/run_raptor`, `/auto_metadata`) preserved alongside new paths
3. **`_VALID_INDEX_TYPES = {"graph", "raptor", "mindmap"}`** — input
validation via constant set
4. **`_INDEX_TYPE_TO_TASK_ID_FIELD`** — maps index type to KB model task
ID field for clean dispatch
## Files Changed
- `api/apps/restful_apis/dataset_api.py`
- `api/apps/services/dataset_api_service.py`
- `sdk/python/ragflow_sdk/modules/dataset.py`
- `test/testcases/test_http_api/common.py`
- `test/testcases/test_http_api/test_dataset_management/` (7 new files)
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- [x] Refactoring
---------
Signed-off-by: noob <yixiao121314@outlook.com>
2026-04-27 01:38:01 +00:00
|
|
|
const { data } = await getKbDetail(knowledgeBaseId || '');
|
2026-04-14 18:07:32 +08:00
|
|
|
return data?.data ?? {};
|
2025-04-25 11:15:44 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading };
|
|
|
|
|
};
|
2025-07-21 19:11:27 +08:00
|
|
|
|
|
|
|
|
export function useFetchKnowledgeGraph() {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
|
|
|
|
|
const { data, isFetching: loading } = useQuery<IKnowledgeGraph>({
|
2025-08-12 10:15:10 +08:00
|
|
|
queryKey: [KnowledgeApiAction.FetchKnowledgeGraph, knowledgeBaseId],
|
2025-07-21 19:11:27 +08:00
|
|
|
initialData: { graph: {}, mind_map: {} } as IKnowledgeGraph,
|
|
|
|
|
enabled: !!knowledgeBaseId,
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
queryFn: async () => {
|
|
|
|
|
const { data } = await getKnowledgeGraph(knowledgeBaseId);
|
|
|
|
|
return data?.data;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading };
|
|
|
|
|
}
|
2025-08-12 10:15:10 +08:00
|
|
|
|
|
|
|
|
export function useFetchKnowledgeMetadata(kbIds: string[] = []) {
|
|
|
|
|
const { data, isFetching: loading } = useQuery<
|
|
|
|
|
Record<string, Record<string, string[]>>
|
|
|
|
|
>({
|
|
|
|
|
queryKey: [KnowledgeApiAction.FetchMetadata, kbIds],
|
|
|
|
|
initialData: {},
|
|
|
|
|
enabled: kbIds.length > 0,
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
queryFn: async () => {
|
feat(api): add unified index API and dataset management endpoints (#14222)
### What problem does this PR solve?
## Summary
Refactor the dataset API layer into a clean service/REST separation
pattern, add a unified `/index` API for graph/raptor/mindmap operations,
and introduce several new dataset management endpoints with full test
coverage.
## Changes
### Service Layer (`dataset_api_service.py`)
- Added `trace_index(dataset_id, tenant_id, index_type)` — unified trace
function for all index types
- Added `run_index`, `delete_index` service functions
- Added `get_dataset`, `get_ingestion_summary`, `list_ingestion_logs`,
`get_ingestion_log`
- Added `run_embedding`, `list_tags`, `aggregate_tags`, `delete_tags`,
`rename_tag`
- Added `get_flattened_metadata`, `get_auto_metadata`,
`update_auto_metadata`
### REST API Layer (`dataset_api.py`)
**New unified routes:**
| Method | Route | Description |
|--------|-------|-------------|
| POST | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Run index
task |
| GET | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Trace index
task |
| DELETE | `/datasets/<id>/<index_type>` | Delete index |
| GET | `/datasets/<id>` | Get dataset details |
| GET | `/datasets/<id>/ingestions/summary` | Ingestion summary |
| GET | `/datasets/<id>/ingestions` | List ingestion logs |
| GET | `/datasets/<id>/ingestions/<log_id>` | Get single ingestion log
|
| POST | `/datasets/<id>/embedding` | Run embedding |
| GET | `/datasets/<id>/tags` | List tags |
| GET | `/datasets/tags/aggregation` | Aggregate tags across datasets |
| DELETE | `/datasets/<id>/tags` | Delete tags |
| PUT | `/datasets/<id>/tags` | Rename tag |
| GET | `/datasets/metadata/flattened` | Get flattened metadata |
| GET/PUT | `/datasets/<id>/metadata/config` | New metadata config path
|
**Removed routes (replaced by unified `/index`):**
- `POST /datasets/<id>/mindmap`
- `GET /datasets/<id>/mindmap`
**Preserved legacy routes (backward compatibility):**
- `/run_graphrag`, `/trace_graphrag`, `/run_raptor`, `/trace_raptor`
- `/auto_metadata` GET/PUT
### Test Suite
- Updated `common.py` helpers: added `trace_index`, removed
`run_mindmap`/`trace_mindmap`
- Added 7 new test files with 39 test cases total:
| Test File | Cases |
|-----------|-------|
| `test_get_dataset.py` | 4 |
| `test_ingestion_summary.py` | 2 |
| `test_ingestion_logs.py` | 5 |
| `test_index_api.py` | 14 |
| `test_embedding.py` | 2 |
| `test_tags.py` | 8 |
| `test_flattened_metadata.py` | 4 |
- Deleted `test_mindmap_tasks.py` (covered by unified index tests)
## Design Decisions
1. **Unified `/index?type=...`** — single endpoint replaces 3 separate
route pairs for graph/raptor/mindmap
2. **Backward compatibility** — old routes (`/run_graphrag`,
`/run_raptor`, `/auto_metadata`) preserved alongside new paths
3. **`_VALID_INDEX_TYPES = {"graph", "raptor", "mindmap"}`** — input
validation via constant set
4. **`_INDEX_TYPE_TO_TASK_ID_FIELD`** — maps index type to KB model task
ID field for clean dispatch
## Files Changed
- `api/apps/restful_apis/dataset_api.py`
- `api/apps/services/dataset_api_service.py`
- `sdk/python/ragflow_sdk/modules/dataset.py`
- `test/testcases/test_http_api/common.py`
- `test/testcases/test_http_api/test_dataset_management/` (7 new files)
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- [x] Refactoring
---------
Signed-off-by: noob <yixiao121314@outlook.com>
2026-04-27 01:38:01 +00:00
|
|
|
const { data } = await kbService.getMeta({
|
|
|
|
|
dataset_ids: kbIds.join(','),
|
|
|
|
|
});
|
2025-08-12 10:15:10 +08:00
|
|
|
return data?.data ?? {};
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading };
|
|
|
|
|
}
|
2025-09-28 12:18:58 +08:00
|
|
|
|
2026-04-30 18:13:27 +03:00
|
|
|
export function useFetchKnowledgeMetadataKeys(kbIds: string[] = []) {
|
|
|
|
|
const sortedKbIds = useMemo(() => [...kbIds].sort(), [kbIds]);
|
|
|
|
|
const { data, isFetching: loading } = useQuery<string[]>({
|
|
|
|
|
queryKey: [KnowledgeApiAction.FetchMetadataKeys, sortedKbIds],
|
|
|
|
|
initialData: [],
|
|
|
|
|
enabled: sortedKbIds.length > 0,
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
queryFn: async () => {
|
|
|
|
|
const { data } = await kbService.getMetaKeys({
|
|
|
|
|
kb_ids: sortedKbIds.join(','),
|
|
|
|
|
});
|
|
|
|
|
return data?.data ?? [];
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading };
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-28 12:18:58 +08:00
|
|
|
export const useRemoveKnowledgeGraph = () => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: [KnowledgeApiAction.RemoveKnowledgeGraph],
|
|
|
|
|
mutationFn: async () => {
|
|
|
|
|
const { data } = await deleteKnowledgeGraph(knowledgeBaseId);
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(i18n.t(`message.deleted`));
|
|
|
|
|
queryClient.invalidateQueries({
|
2025-10-09 13:55:36 +08:00
|
|
|
queryKey: [KnowledgeApiAction.FetchKnowledgeGraph],
|
2025-09-28 12:18:58 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data?.code;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, removeKnowledgeGraph: mutateAsync };
|
|
|
|
|
};
|
2025-10-09 12:36:19 +08:00
|
|
|
|
|
|
|
|
export const useFetchKnowledgeList = (
|
|
|
|
|
shouldFilterListWithoutDocument: boolean = false,
|
2026-05-12 19:36:23 +08:00
|
|
|
keywords = '',
|
2025-10-09 12:36:19 +08:00
|
|
|
): {
|
2026-04-14 18:07:32 +08:00
|
|
|
list: IDataset[];
|
2025-10-09 12:36:19 +08:00
|
|
|
loading: boolean;
|
|
|
|
|
} => {
|
|
|
|
|
const { data, isFetching: loading } = useQuery({
|
2026-05-12 19:36:23 +08:00
|
|
|
queryKey: [
|
|
|
|
|
KnowledgeApiAction.FetchKnowledgeList,
|
|
|
|
|
shouldFilterListWithoutDocument,
|
|
|
|
|
keywords,
|
|
|
|
|
],
|
2025-10-09 12:36:19 +08:00
|
|
|
initialData: [],
|
|
|
|
|
gcTime: 0, // https://tanstack.com/query/latest/docs/framework/react/guides/caching?from=reactQueryV3
|
|
|
|
|
queryFn: async () => {
|
2026-05-12 19:36:23 +08:00
|
|
|
const { data } = await listDataset(
|
|
|
|
|
keywords
|
|
|
|
|
? {
|
|
|
|
|
ext: {
|
|
|
|
|
keywords,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
: undefined,
|
|
|
|
|
);
|
2026-03-19 14:41:36 +08:00
|
|
|
const list = data?.data ?? [];
|
2025-10-09 12:36:19 +08:00
|
|
|
return shouldFilterListWithoutDocument
|
2026-04-14 18:07:32 +08:00
|
|
|
? list.filter((x: IDataset) => x.chunk_count > 0)
|
2025-10-09 12:36:19 +08:00
|
|
|
: list;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { list: data, loading };
|
|
|
|
|
};
|
2025-12-02 17:24:29 +08:00
|
|
|
|
|
|
|
|
export const useSelectKnowledgeOptions = () => {
|
|
|
|
|
const { list } = useFetchKnowledgeList();
|
|
|
|
|
|
|
|
|
|
const options = list?.map((item) => ({
|
|
|
|
|
label: item.name,
|
|
|
|
|
value: item.id,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
return options;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//#region tags
|
|
|
|
|
export const useRenameTag = () => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: ['renameTag'],
|
|
|
|
|
mutationFn: async (params: IRenameTag) => {
|
|
|
|
|
const { data } = await renameTag(knowledgeBaseId, params);
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(i18n.t(`message.modified`));
|
|
|
|
|
queryClient.invalidateQueries({
|
|
|
|
|
queryKey: ['fetchTagList'],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data?.data ?? [];
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, renameTag: mutateAsync };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useTagIsRenaming = () => {
|
|
|
|
|
return useIsMutating({ mutationKey: ['renameTag'] }) > 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useFetchTagListByKnowledgeIds = () => {
|
|
|
|
|
const [knowledgeIds, setKnowledgeIds] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
const { data, isFetching: loading } = useQuery<Array<[string, number]>>({
|
2026-05-26 20:24:22 +08:00
|
|
|
queryKey: ['fetchTagListByKnowledgeIds', knowledgeIds],
|
2025-12-02 17:24:29 +08:00
|
|
|
enabled: knowledgeIds.length > 0,
|
|
|
|
|
initialData: [],
|
|
|
|
|
gcTime: 0, // https://tanstack.com/query/latest/docs/framework/react/guides/caching?from=reactQueryV3
|
|
|
|
|
queryFn: async () => {
|
|
|
|
|
const { data } = await kbService.listTagByKnowledgeIds({
|
feat(api): add unified index API and dataset management endpoints (#14222)
### What problem does this PR solve?
## Summary
Refactor the dataset API layer into a clean service/REST separation
pattern, add a unified `/index` API for graph/raptor/mindmap operations,
and introduce several new dataset management endpoints with full test
coverage.
## Changes
### Service Layer (`dataset_api_service.py`)
- Added `trace_index(dataset_id, tenant_id, index_type)` — unified trace
function for all index types
- Added `run_index`, `delete_index` service functions
- Added `get_dataset`, `get_ingestion_summary`, `list_ingestion_logs`,
`get_ingestion_log`
- Added `run_embedding`, `list_tags`, `aggregate_tags`, `delete_tags`,
`rename_tag`
- Added `get_flattened_metadata`, `get_auto_metadata`,
`update_auto_metadata`
### REST API Layer (`dataset_api.py`)
**New unified routes:**
| Method | Route | Description |
|--------|-------|-------------|
| POST | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Run index
task |
| GET | `/datasets/<id>/index?type=graph\|raptor\|mindmap` | Trace index
task |
| DELETE | `/datasets/<id>/<index_type>` | Delete index |
| GET | `/datasets/<id>` | Get dataset details |
| GET | `/datasets/<id>/ingestions/summary` | Ingestion summary |
| GET | `/datasets/<id>/ingestions` | List ingestion logs |
| GET | `/datasets/<id>/ingestions/<log_id>` | Get single ingestion log
|
| POST | `/datasets/<id>/embedding` | Run embedding |
| GET | `/datasets/<id>/tags` | List tags |
| GET | `/datasets/tags/aggregation` | Aggregate tags across datasets |
| DELETE | `/datasets/<id>/tags` | Delete tags |
| PUT | `/datasets/<id>/tags` | Rename tag |
| GET | `/datasets/metadata/flattened` | Get flattened metadata |
| GET/PUT | `/datasets/<id>/metadata/config` | New metadata config path
|
**Removed routes (replaced by unified `/index`):**
- `POST /datasets/<id>/mindmap`
- `GET /datasets/<id>/mindmap`
**Preserved legacy routes (backward compatibility):**
- `/run_graphrag`, `/trace_graphrag`, `/run_raptor`, `/trace_raptor`
- `/auto_metadata` GET/PUT
### Test Suite
- Updated `common.py` helpers: added `trace_index`, removed
`run_mindmap`/`trace_mindmap`
- Added 7 new test files with 39 test cases total:
| Test File | Cases |
|-----------|-------|
| `test_get_dataset.py` | 4 |
| `test_ingestion_summary.py` | 2 |
| `test_ingestion_logs.py` | 5 |
| `test_index_api.py` | 14 |
| `test_embedding.py` | 2 |
| `test_tags.py` | 8 |
| `test_flattened_metadata.py` | 4 |
- Deleted `test_mindmap_tasks.py` (covered by unified index tests)
## Design Decisions
1. **Unified `/index?type=...`** — single endpoint replaces 3 separate
route pairs for graph/raptor/mindmap
2. **Backward compatibility** — old routes (`/run_graphrag`,
`/run_raptor`, `/auto_metadata`) preserved alongside new paths
3. **`_VALID_INDEX_TYPES = {"graph", "raptor", "mindmap"}`** — input
validation via constant set
4. **`_INDEX_TYPE_TO_TASK_ID_FIELD`** — maps index type to KB model task
ID field for clean dispatch
## Files Changed
- `api/apps/restful_apis/dataset_api.py`
- `api/apps/services/dataset_api_service.py`
- `sdk/python/ragflow_sdk/modules/dataset.py`
- `test/testcases/test_http_api/common.py`
- `test/testcases/test_http_api/test_dataset_management/` (7 new files)
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- [x] Refactoring
---------
Signed-off-by: noob <yixiao121314@outlook.com>
2026-04-27 01:38:01 +00:00
|
|
|
dataset_ids: knowledgeIds.join(','),
|
2025-12-02 17:24:29 +08:00
|
|
|
});
|
2026-05-26 20:24:22 +08:00
|
|
|
const list = (data?.data || []) as Array<
|
|
|
|
|
[string, number] | { value?: string; count?: number }
|
|
|
|
|
>;
|
|
|
|
|
return list.flatMap((tag): Array<[string, number]> => {
|
|
|
|
|
if (Array.isArray(tag)) {
|
|
|
|
|
return [tag];
|
|
|
|
|
}
|
|
|
|
|
return tag.value ? [[tag.value, tag.count ?? 0]] : [];
|
|
|
|
|
});
|
2025-12-02 17:24:29 +08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { list: data, loading, setKnowledgeIds };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useFetchTagList = () => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
|
|
|
|
|
const { data, isFetching: loading } = useQuery<Array<[string, number]>>({
|
|
|
|
|
queryKey: ['fetchTagList'],
|
|
|
|
|
initialData: [],
|
|
|
|
|
gcTime: 0, // https://tanstack.com/query/latest/docs/framework/react/guides/caching?from=reactQueryV3
|
|
|
|
|
queryFn: async () => {
|
|
|
|
|
const { data } = await listTag(knowledgeBaseId);
|
|
|
|
|
const list = data?.data || [];
|
|
|
|
|
return list;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { list: data, loading };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useDeleteTag = () => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
|
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: ['deleteTag'],
|
|
|
|
|
mutationFn: async (tags: string[]) => {
|
|
|
|
|
const { data } = await removeTag(knowledgeBaseId, tags);
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
message.success(i18n.t(`message.deleted`));
|
|
|
|
|
queryClient.invalidateQueries({
|
|
|
|
|
queryKey: ['fetchTagList'],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data?.data ?? [];
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { data, loading, deleteTag: mutateAsync };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// #endregion
|
|
|
|
|
|
|
|
|
|
//#region Retrieval testing
|
|
|
|
|
|
|
|
|
|
export const useTestChunkRetrieval = (): ResponsePostType<ITestingResult> & {
|
|
|
|
|
testChunk: (...params: any[]) => void;
|
|
|
|
|
} => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
const { page, size: pageSize } = useSetPaginationParams();
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: ['testChunk'], // This method is invalid
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
mutationFn: async (values: any) => {
|
2026-04-13 21:07:07 +08:00
|
|
|
const { data } = await kbService.retrievalTest({
|
2025-12-02 17:24:29 +08:00
|
|
|
...values,
|
|
|
|
|
kb_id: values.kb_id ?? knowledgeBaseId,
|
|
|
|
|
page,
|
|
|
|
|
size: pageSize,
|
|
|
|
|
});
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
const res = data.data;
|
|
|
|
|
return {
|
|
|
|
|
...res,
|
|
|
|
|
documents: res.doc_aggs,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return (
|
|
|
|
|
data?.data ?? {
|
|
|
|
|
chunks: [],
|
|
|
|
|
documents: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
data: data ?? { chunks: [], documents: [], total: 0 },
|
|
|
|
|
loading,
|
|
|
|
|
testChunk: mutateAsync,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useTestChunkAllRetrieval = (): ResponsePostType<ITestingResult> & {
|
|
|
|
|
testChunkAll: (...params: any[]) => void;
|
|
|
|
|
} => {
|
|
|
|
|
const knowledgeBaseId = useKnowledgeBaseId();
|
|
|
|
|
const { page, size: pageSize } = useSetPaginationParams();
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data,
|
|
|
|
|
isPending: loading,
|
|
|
|
|
mutateAsync,
|
|
|
|
|
} = useMutation({
|
|
|
|
|
mutationKey: ['testChunkAll'], // This method is invalid
|
|
|
|
|
gcTime: 0,
|
|
|
|
|
mutationFn: async (values: any) => {
|
2026-04-13 21:07:07 +08:00
|
|
|
const { data } = await kbService.retrievalTest({
|
2025-12-02 17:24:29 +08:00
|
|
|
...values,
|
|
|
|
|
kb_id: values.kb_id ?? knowledgeBaseId,
|
|
|
|
|
doc_ids: [],
|
|
|
|
|
page,
|
|
|
|
|
size: pageSize,
|
|
|
|
|
});
|
|
|
|
|
if (data.code === 0) {
|
|
|
|
|
const res = data.data;
|
|
|
|
|
return {
|
|
|
|
|
...res,
|
|
|
|
|
documents: res.doc_aggs,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return (
|
|
|
|
|
data?.data ?? {
|
|
|
|
|
chunks: [],
|
|
|
|
|
documents: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
data: data ?? { chunks: [], documents: [], total: 0 },
|
|
|
|
|
loading,
|
|
|
|
|
testChunkAll: mutateAsync,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useChunkIsTesting = () => {
|
|
|
|
|
return useIsMutating({ mutationKey: ['testChunk'] }) > 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useSelectTestingResult = (): ITestingResult => {
|
|
|
|
|
const data = useMutationState({
|
|
|
|
|
filters: { mutationKey: ['testChunk'] },
|
|
|
|
|
select: (mutation) => {
|
|
|
|
|
return mutation.state.data;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return (data.at(-1) ?? {
|
|
|
|
|
chunks: [],
|
|
|
|
|
documents: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
}) as ITestingResult;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useSelectIsTestingSuccess = () => {
|
|
|
|
|
const status = useMutationState({
|
|
|
|
|
filters: { mutationKey: ['testChunk'] },
|
|
|
|
|
select: (mutation) => {
|
|
|
|
|
return mutation.state.status;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return status.at(-1) === 'success';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useAllTestingSuccess = () => {
|
|
|
|
|
const status = useMutationState({
|
|
|
|
|
filters: { mutationKey: ['testChunkAll'] },
|
|
|
|
|
select: (mutation) => {
|
|
|
|
|
return mutation.state.status;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return status.at(-1) === 'success';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const useAllTestingResult = (): ITestingResult => {
|
|
|
|
|
const data = useMutationState({
|
|
|
|
|
filters: { mutationKey: ['testChunkAll'] },
|
|
|
|
|
select: (mutation) => {
|
|
|
|
|
return mutation.state.data;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return (data.at(-1) ?? {
|
|
|
|
|
chunks: [],
|
|
|
|
|
documents: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
}) as ITestingResult;
|
|
|
|
|
};
|
|
|
|
|
//#endregion
|