Skip to content

Commit ba43cfb

Browse files
authored
Merge pull request #1250 from yixinmeng/feat/persist-ragflow-dataset-id
feat: persist ragflow dataset id and route by id
2 parents f7bd819 + ec867fa commit ba43cfb

40 files changed

Lines changed: 1797 additions & 960 deletions

File tree

console/backend/commons/src/main/java/com/iflytek/astron/console/commons/constant/ResponseEnum.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ public enum ResponseEnum {
395395
REPO_KNOWLEDGE_QUERY_FAILED(8737, "repo.knowledge.query.failed"),
396396
REPO_DELETE_FAILED_BOT_USED(8738, "repo.delete.failed.bot.used"),
397397
REPO_FILE_UPLOAD_TYPE_NOT_EXIST(8739, "repo.file.upload.type.not.exist"),
398+
REPO_CREATE_RAGFLOW_FAILED(8740, "repo.create.ragflow.failed"),
398399

399400
// 8900 - 9000 (Model related)
400401
MODEL_NOT_COMPATIBLE_OPENAI(8900, "model.not.compatible.openai"),

console/backend/commons/src/main/resources/messages_en.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ repo.file.disabled=Document disabled
376376
repo.knowledge.query.failed=Knowledge retrieval failed
377377
repo.delete.failed.bot.used=Knowledge base has bot association usage, cannot delete
378378
repo.file.upload.type.not.exist=Upload failed: File type not supported
379+
repo.create.ragflow.failed=Failed to create RAGFlow dataset: {0}
379380

380381
# Model 8900+
381382
model.not.compatible.openai=Interface return format not compatible with OpenAI protocol

console/backend/commons/src/main/resources/messages_zh.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ repo.file.disabled=文档已停用
388388
repo.knowledge.query.failed=知识检索失败
389389
repo.delete.failed.bot.used=知识库存在bot关联使用,不能删除
390390
repo.file.upload.type.not.exist=上传失败:文件类型不支持
391+
repo.create.ragflow.failed=RAGFlow 知识库创建失败:{0}
391392

392393
# 模型 8900+
393394
model.not.compatible.openai=接口返回格式不兼容 OpenAI 协议
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE repo
2+
ADD COLUMN ragflow_dataset_id VARCHAR(64) NULL
3+
COMMENT 'RAGFlow dataset.id for Ragflow-RAG repos; NULL uses the default dataset';
4+
5+
CREATE INDEX idx_repo_ragflow_dataset_id ON repo (ragflow_dataset_id);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.iflytek.astron.console.toolkit.entity.core.knowledge;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
/** Request body for POST /v1/dataset/create. */
8+
@Data
9+
@NoArgsConstructor
10+
@AllArgsConstructor
11+
public class DatasetCreateRequest {
12+
13+
String name;
14+
15+
String description;
16+
}

console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/entity/core/knowledge/KnowledgeRequest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public class KnowledgeRequest {
1717
*/
1818
String group;
1919

20+
/** RAGFlow dataset.id for Ragflow-RAG routing; blank uses the default dataset. */
21+
String datasetId;
22+
2023
/**
2124
* Required: No. User ID to which the document belongs, users can specify themselves
2225
*/

console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/entity/core/knowledge/QueryMatchObj.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public class QueryMatchObj {
1616
*/
1717
List<String> repoId;
1818

19+
/** RAGFlow dataset.id values for Ragflow-RAG routing. */
20+
List<String> datasetId;
21+
1922
/**
2023
* Required: No. Knowledge base score threshold, default 0
2124
*/

console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/entity/core/knowledge/SplitRequest.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,8 @@ public class SplitRequest {
5050
*/
5151
Integer resourceType;
5252

53-
/**
54-
* RAGFlow dataset group (coreRepoId for Ragflow-RAG). Optional; null falls back to the default
55-
* group.
56-
*/
57-
String group;
58-
59-
/**
60-
* Human-readable label written into the RAGFlow dataset description on first creation. Helps
61-
* operators identify the dataset in the RAGFlow UI without resolving UUIDs.
62-
*/
63-
String groupDescription;
53+
/** RAGFlow dataset.id for Ragflow-RAG routing; blank uses the default dataset. */
54+
String datasetId;
6455

6556
// Default to AIUI value
6657
public SplitRequest() {

console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/entity/table/repo/Repo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ public class Repo implements Serializable {
121121
// Knowledge base type, CBG-RAG / AIUI-RAG2
122122
private String tag;
123123

124+
/** RAGFlow dataset.id for Ragflow-RAG repos; null uses the default dataset. */
125+
private String ragflowDatasetId;
126+
124127
private Long spaceId;
125128

126129
}
Lines changed: 70 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.iflytek.astron.console.toolkit.handler;
22

33
import com.alibaba.fastjson2.JSON;
4+
import com.alibaba.fastjson2.JSONObject;
5+
import com.iflytek.astron.console.commons.constant.ResponseEnum;
6+
import com.iflytek.astron.console.commons.exception.BusinessException;
47
import com.iflytek.astron.console.toolkit.common.constant.ProjectContent;
58
import com.iflytek.astron.console.toolkit.config.properties.RepoAuthorizedConfig;
69
import com.iflytek.astron.console.toolkit.config.properties.ApiUrl;
@@ -25,25 +28,63 @@ public class KnowledgeV2ServiceCallHandler {
2528
@Resource
2629
private RepoAuthorizedConfig repoAuthorizedConfig;
2730

31+
private static final String DATASET_ID_FIELD = "datasetId";
32+
33+
/**
34+
* Create or reuse a RAGFlow dataset and return its id.
35+
*
36+
* @param name RAGFlow dataset.name
37+
* @param description RAGFlow dataset.description; nullable
38+
*/
39+
public String createRagflowDataset(String name, String description) {
40+
String url = apiUrl.getKnowledgeUrl().concat("/v1/dataset/create");
41+
DatasetCreateRequest req = new DatasetCreateRequest(name, description);
42+
String reqBody = JSON.toJSONString(req);
43+
log.info("createRagflowDataset url = {}, name = {}", url, name);
44+
String resp = postJson(url, reqBody);
45+
log.info("createRagflowDataset response = {}", resp);
46+
KnowledgeResponse parsed = JSON.parseObject(resp, KnowledgeResponse.class);
47+
if (parsed == null || parsed.getCode() == null || parsed.getCode() != 0) {
48+
String msg = (parsed == null) ? "blank response" : parsed.getMessage();
49+
throw new BusinessException(ResponseEnum.REPO_CREATE_RAGFLOW_FAILED, msg);
50+
}
51+
return extractDatasetId(parsed.getData());
52+
}
53+
54+
private String extractDatasetId(Object data) {
55+
JSONObject dataObj = toJsonObject(data);
56+
String datasetId = dataObj == null ? null : dataObj.getString(DATASET_ID_FIELD);
57+
if (StringUtils.isBlank(datasetId)) {
58+
throw new BusinessException(ResponseEnum.REPO_CREATE_RAGFLOW_FAILED,
59+
"RAGFlow returned blank datasetId");
60+
}
61+
return datasetId;
62+
}
63+
64+
private JSONObject toJsonObject(Object data) {
65+
if (data instanceof JSONObject) {
66+
return (JSONObject) data;
67+
}
68+
if (data instanceof String) {
69+
return JSON.parseObject((String) data);
70+
}
71+
throw new BusinessException(ResponseEnum.REPO_CREATE_RAGFLOW_FAILED,
72+
"RAGFlow returned non-object data");
73+
}
74+
2875
/**
2976
* Document parsing and chunking
3077
*
3178
* @param request the split request describing the document
32-
* @param coreRepoId Ragflow-RAG dataset name/group; forwarded as {@code group} so the upstream
33-
* service can resolve the matching dataset. Ignored for non-Ragflow-RAG sources to keep
34-
* CBG/AIUI/Spark behavior intact.
35-
* @param repoName human-readable repo display name; written into RAGFlow dataset description on
36-
* first lazy creation. Pass {@code null} to skip.
79+
* @param datasetId RAGFlow dataset.id; ignored when blank or non-Ragflow
3780
* @return knowledge response from the upstream split API
3881
*/
39-
public KnowledgeResponse documentSplit(
40-
SplitRequest request, String coreRepoId, String repoName) {
41-
applyGroupToSplitRequest(request, coreRepoId);
42-
applyGroupDescriptionToSplitRequest(request, repoName);
82+
public KnowledgeResponse documentSplit(SplitRequest request, String datasetId) {
83+
applyDatasetIdToSplitRequest(request, datasetId);
4384
String url = apiUrl.getKnowledgeUrl().concat("/v1/document/split");
4485
String reqBody = JSON.toJSONString(request);
4586
log.info("documentSplit url = {}, request = {}", url, reqBody);
46-
String post = OkHttpUtil.post(url, reqBody);
87+
String post = postJson(url, reqBody);
4788
log.info("documentSplit response = {}", post);
4889
return JSON.parseObject(post, KnowledgeResponse.class);
4990
}
@@ -57,19 +98,14 @@ public KnowledgeResponse documentSplit(
5798
* @param ragType RAG type
5899
* @param resourceType resource type (0=file, 1=html)
59100
* @param oldDocId existing RAGFlow doc id for upsert; null for first slice
60-
* @param coreRepoId Ragflow-RAG dataset name/group; forwarded as {@code group} so the upstream
61-
* service can resolve the matching dataset. Ignored for non-Ragflow-RAG sources to keep
62-
* CBG/AIUI/Spark behavior intact.
63-
* @param repoName human-readable repo display name; written into RAGFlow dataset description on
64-
* first lazy creation. Pass {@code null} to skip.
101+
* @param datasetId RAGFlow dataset.id; ignored when blank or non-Ragflow
65102
* @return KnowledgeResponse
66103
*/
67104
public KnowledgeResponse documentUpload(MultipartFile multipartFile,
68105
List<Integer> lengthRange, List<String> separator,
69106
String ragType, Integer resourceType,
70107
String oldDocId,
71-
String coreRepoId,
72-
String repoName) {
108+
String datasetId) {
73109
String url = apiUrl.getKnowledgeUrl().concat("/v1/document/upload");
74110

75111
try {
@@ -91,11 +127,10 @@ public KnowledgeResponse documentUpload(MultipartFile multipartFile,
91127
if (StringUtils.isNotBlank(oldDocId)) {
92128
params.put("documentId", oldDocId);
93129
}
94-
applyGroupToUploadParams(params, ragType, coreRepoId);
95-
applyGroupDescriptionToUploadParams(params, ragType, repoName);
130+
applyDatasetIdToUploadParams(params, ragType, datasetId);
96131

97132
log.info("documentUpload url = {}, ragType = {}, resourceType = {}", url, ragType, resourceType);
98-
String post = OkHttpUtil.postMultipart(url, new HashMap<>(), null, params, null);
133+
String post = OkHttpUtil.postMultipart(url, null, null, params, null);
99134
log.info("documentUpload response = {}", post);
100135
return JSON.parseObject(post, KnowledgeResponse.class);
101136
} catch (Exception e) {
@@ -107,68 +142,32 @@ public KnowledgeResponse documentUpload(MultipartFile multipartFile,
107142
}
108143
}
109144

110-
/**
111-
* Set {@code group} on the split request for Ragflow-RAG when {@code coreRepoId} is non-blank.
112-
* No-op otherwise so other RAG strategies stay untouched.
113-
*/
114-
void applyGroupToSplitRequest(SplitRequest request, String coreRepoId) {
115-
if (request == null) {
116-
return;
117-
}
118-
if (ProjectContent.FILE_SOURCE_RAG_FLOW_RAG_STR.equals(request.getRagType())
119-
&& StringUtils.isNotBlank(coreRepoId)) {
120-
request.setGroup(coreRepoId);
121-
}
122-
}
123-
124-
/**
125-
* Add {@code group} to the upload params map for Ragflow-RAG when {@code coreRepoId} is non-blank.
126-
* No-op otherwise.
127-
*/
128-
void applyGroupToUploadParams(Map<String, Object> params, String ragType, String coreRepoId) {
129-
if (params == null) {
130-
return;
131-
}
132-
if (ProjectContent.FILE_SOURCE_RAG_FLOW_RAG_STR.equals(ragType)
133-
&& StringUtils.isNotBlank(coreRepoId)) {
134-
params.put("group", coreRepoId);
135-
}
136-
}
137-
138-
/**
139-
* Set {@code groupDescription} on the split request for Ragflow-RAG when {@code repoName} is
140-
* non-blank. No-op otherwise.
141-
*/
142-
void applyGroupDescriptionToSplitRequest(SplitRequest request, String repoName) {
145+
void applyDatasetIdToSplitRequest(SplitRequest request, String datasetId) {
143146
if (request == null) {
144147
return;
145148
}
146149
if (ProjectContent.FILE_SOURCE_RAG_FLOW_RAG_STR.equals(request.getRagType())
147-
&& StringUtils.isNotBlank(repoName)) {
148-
request.setGroupDescription(repoName);
150+
&& StringUtils.isNotBlank(datasetId)) {
151+
request.setDatasetId(datasetId);
149152
}
150153
}
151154

152-
/**
153-
* Add {@code groupDescription} to the upload params map for Ragflow-RAG when {@code repoName} is
154-
* non-blank. No-op otherwise.
155-
*/
156-
void applyGroupDescriptionToUploadParams(
157-
Map<String, Object> params, String ragType, String repoName) {
155+
void applyDatasetIdToUploadParams(
156+
Map<String, Object> params, String ragType, String datasetId) {
158157
if (params == null) {
159158
return;
160159
}
161160
if (ProjectContent.FILE_SOURCE_RAG_FLOW_RAG_STR.equals(ragType)
162-
&& StringUtils.isNotBlank(repoName)) {
163-
params.put("groupDescription", repoName);
161+
&& StringUtils.isNotBlank(datasetId)) {
162+
params.put(DATASET_ID_FIELD, datasetId);
164163
}
165164
}
166165

167166
public KnowledgeResponse saveChunk(KnowledgeRequest request) {
168167
String url = apiUrl.getKnowledgeUrl().concat("/v1/chunks/save");
169168
String reqBody = JSON.toJSONString(request);
170169
log.info("saveChunk url = {}, request = {}", url, reqBody);
171-
String post = OkHttpUtil.post(url, reqBody);
170+
String post = postJson(url, reqBody);
172171
log.info("saveChunk response = {}", post);
173172
return JSON.parseObject(post, KnowledgeResponse.class);
174173
}
@@ -177,7 +176,7 @@ public KnowledgeResponse updateChunk(KnowledgeRequest request) {
177176
String url = apiUrl.getKnowledgeUrl().concat("/v1/chunk/update");
178177
String reqBody = JSON.toJSONString(request);
179178
log.info("updateChunk url = {}, request = {}", url, reqBody);
180-
String post = OkHttpUtil.post(url, reqBody);
179+
String post = postJson(url, reqBody);
181180
log.info("updateChunk response = {}", post);
182181
return JSON.parseObject(post, KnowledgeResponse.class);
183182
}
@@ -186,7 +185,7 @@ public KnowledgeResponse deleteDocOrChunk(KnowledgeRequest request) {
186185
String url = apiUrl.getKnowledgeUrl().concat("/v1/chunk/delete");
187186
String reqBody = JSON.toJSONString(request);
188187
log.info("deleteDocOrChunk url = {}, request = {}", url, reqBody);
189-
String post = OkHttpUtil.post(url, reqBody);
188+
String post = postJson(url, reqBody);
190189
log.info("deleteDocOrChunk response = {}", post);
191190
return JSON.parseObject(post, KnowledgeResponse.class);
192191
}
@@ -195,8 +194,12 @@ public KnowledgeResponse knowledgeQuery(QueryRequest request) {
195194
String url = apiUrl.getKnowledgeUrl().concat("/v1/chunk/query");
196195
String reqBody = JSON.toJSONString(request);
197196
log.info("knowledgeQuery request url:{}\ndata:{}", url, reqBody);
198-
String respData = OkHttpUtil.post(url, reqBody);
197+
String respData = postJson(url, reqBody);
199198
log.info("knowledgeQuery response data:{}", respData);
200199
return JSON.parseObject(respData, KnowledgeResponse.class);
201200
}
201+
202+
private String postJson(String url, String reqBody) {
203+
return OkHttpUtil.post(url, reqBody);
204+
}
202205
}

0 commit comments

Comments
 (0)