feat: 完成管理端聊天工作台收口
- 新增管理端聊天工作台与会话级额外知识库持久化 - 补齐发布态聊天、历史会话只读判断与答案版本切换 - 新增 chat_round 热数据与主线消息读取支撑
This commit is contained in:
@@ -121,11 +121,12 @@ public class BotServiceImplTest {
|
||||
List.class,
|
||||
Bot.class,
|
||||
boolean.class,
|
||||
ChatTimeToolAvailabilityContext.class
|
||||
ChatTimeToolAvailabilityContext.class,
|
||||
Set.class
|
||||
);
|
||||
method.setAccessible(true);
|
||||
|
||||
method.invoke(service, functionList, runtimeBot, false, buildContext(12, 3));
|
||||
method.invoke(service, functionList, runtimeBot, false, buildContext(12, 3), new LinkedHashSet<>());
|
||||
|
||||
Assert.assertEquals(1, functionList.size());
|
||||
DocumentCollectionTool tool = (DocumentCollectionTool) functionList.get(0);
|
||||
@@ -133,6 +134,102 @@ public class BotServiceImplTest {
|
||||
Assert.assertEquals(RetrievalMode.KEYWORD, tool.getRetrievalMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 额外知识库应按用户选择顺序去重,并限制最多 3 个。
|
||||
*
|
||||
* @throws Exception 反射调用异常
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sanitizeExtraKnowledgeIdsShouldDeduplicateAndKeepOrder() throws Exception {
|
||||
BotServiceImpl service = new BotServiceImpl();
|
||||
Method method = BotServiceImpl.class.getDeclaredMethod("sanitizeExtraKnowledgeIds", List.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
List<BigInteger> result = (List<BigInteger>) method.invoke(
|
||||
service,
|
||||
List.of(
|
||||
BigInteger.valueOf(3),
|
||||
BigInteger.valueOf(1),
|
||||
BigInteger.valueOf(3),
|
||||
BigInteger.valueOf(2)
|
||||
)
|
||||
);
|
||||
|
||||
Assert.assertEquals(
|
||||
List.of(BigInteger.valueOf(3), BigInteger.ONE, BigInteger.valueOf(2)),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 额外知识库超过 3 个时应直接拒绝请求。
|
||||
*
|
||||
* @throws Exception 反射调用异常
|
||||
*/
|
||||
@Test
|
||||
public void sanitizeExtraKnowledgeIdsShouldRejectWhenMoreThanThree() throws Exception {
|
||||
BotServiceImpl service = new BotServiceImpl();
|
||||
Method method = BotServiceImpl.class.getDeclaredMethod("sanitizeExtraKnowledgeIds", List.class);
|
||||
method.setAccessible(true);
|
||||
|
||||
try {
|
||||
method.invoke(
|
||||
service,
|
||||
List.of(
|
||||
BigInteger.ONE,
|
||||
BigInteger.valueOf(2),
|
||||
BigInteger.valueOf(3),
|
||||
BigInteger.valueOf(4)
|
||||
)
|
||||
);
|
||||
Assert.fail("expected BusinessException");
|
||||
} catch (java.lang.reflect.InvocationTargetException exception) {
|
||||
Assert.assertTrue(exception.getTargetException() instanceof tech.easyflow.common.web.exceptions.BusinessException);
|
||||
Assert.assertEquals("额外知识库最多选择 3 个", exception.getTargetException().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 额外知识库工具应强制使用发布态视图,并跳过重复选择。
|
||||
*
|
||||
* @throws Exception 反射注入异常
|
||||
*/
|
||||
@Test
|
||||
public void appendExtraKnowledgeToolsShouldUsePublishedKnowledgeAndDeduplicate() throws Exception {
|
||||
BotServiceImpl service = new BotServiceImpl();
|
||||
injectAvailabilityService(service, buildAvailabilityService(
|
||||
new RoleCategoryAccessSnapshot("KNOWLEDGE", BigInteger.valueOf(12), false, false, setOf(BigInteger.valueOf(21))),
|
||||
Collections.emptySet()
|
||||
));
|
||||
|
||||
DocumentCollection draftKnowledge = buildKnowledge(101, 11, 21, "PUBLIC");
|
||||
draftKnowledge.setPublishStatus("PUBLISHED");
|
||||
draftKnowledge.setTitle("draft-title");
|
||||
draftKnowledge.setDescription("draft-desc");
|
||||
|
||||
DocumentCollection publishedKnowledge = buildKnowledge(101, 11, 21, "PUBLIC");
|
||||
publishedKnowledge.setPublishStatus("PUBLISHED");
|
||||
publishedKnowledge.setTitle("published-title");
|
||||
publishedKnowledge.setDescription("published-desc");
|
||||
|
||||
injectDocumentCollectionService(service, mockDocumentCollectionServiceForExtra(draftKnowledge, publishedKnowledge));
|
||||
|
||||
List<Tool> tools = new ArrayList<>();
|
||||
service.appendExtraKnowledgeTools(
|
||||
tools,
|
||||
List.of(BigInteger.valueOf(101), BigInteger.valueOf(101)),
|
||||
false,
|
||||
buildContext(12, 3),
|
||||
new LinkedHashSet<>()
|
||||
);
|
||||
|
||||
Assert.assertEquals(1, tools.size());
|
||||
DocumentCollectionTool tool = (DocumentCollectionTool) tools.get(0);
|
||||
Assert.assertEquals(BigInteger.valueOf(101), tool.getKnowledgeId());
|
||||
Assert.assertEquals("published-desc", tool.getDescription());
|
||||
}
|
||||
|
||||
private void injectAvailabilityService(BotServiceImpl service, ChatTimeToolAvailabilityService availabilityService) throws Exception {
|
||||
Field field = BotServiceImpl.class.getDeclaredField("chatTimeToolAvailabilityService");
|
||||
field.setAccessible(true);
|
||||
@@ -189,6 +286,7 @@ public class BotServiceImplTest {
|
||||
knowledge.setCreatedBy(BigInteger.valueOf(createdBy));
|
||||
knowledge.setCategoryId(BigInteger.valueOf(categoryId));
|
||||
knowledge.setVisibilityScope(visibilityScope);
|
||||
knowledge.setPublishStatus("PUBLISHED");
|
||||
return knowledge;
|
||||
}
|
||||
|
||||
@@ -216,6 +314,26 @@ public class BotServiceImplTest {
|
||||
);
|
||||
}
|
||||
|
||||
private tech.easyflow.ai.service.DocumentCollectionService mockDocumentCollectionServiceForExtra(DocumentCollection draftCollection,
|
||||
DocumentCollection publishedCollection) {
|
||||
return (tech.easyflow.ai.service.DocumentCollectionService) Proxy.newProxyInstance(
|
||||
tech.easyflow.ai.service.DocumentCollectionService.class.getClassLoader(),
|
||||
new Class<?>[]{tech.easyflow.ai.service.DocumentCollectionService.class},
|
||||
(proxy, method, args) -> {
|
||||
if ("getById".equals(method.getName())) {
|
||||
return draftCollection;
|
||||
}
|
||||
if ("toPublishedView".equals(method.getName())) {
|
||||
return publishedCollection;
|
||||
}
|
||||
if ("getPublishedById".equals(method.getName())) {
|
||||
return publishedCollection;
|
||||
}
|
||||
return defaultValue(method.getReturnType());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private CategoryPermissionService mockCategoryPermissionService(RoleCategoryAccessSnapshot accessSnapshot) {
|
||||
return (CategoryPermissionService) Proxy.newProxyInstance(
|
||||
CategoryPermissionService.class.getClassLoader(),
|
||||
|
||||
Reference in New Issue
Block a user