feat: 收口聊天时知识库工具可见性

- 新增 chatTime 工具可见性抽象与知识库 resolver

- 聊天装配链路按当前用户过滤知识库工具并补齐调用兜底

- 补充聊天时显式登录快照与对应后端测试
This commit is contained in:
2026-05-11 20:54:13 +08:00
parent ff863e3c27
commit c1590b0d8a
15 changed files with 1441 additions and 25 deletions

View File

@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import tech.easyflow.admin.controller.ai.support.AiResourceCreatorNameSupport;
import tech.easyflow.ai.chattime.availability.ChatTimeToolAvailabilityContext;
import tech.easyflow.ai.easyagents.listener.PromptChoreChatStreamListener;
import tech.easyflow.ai.entity.*;
import tech.easyflow.ai.publish.BotPublishAppService;
@@ -407,23 +408,32 @@ public class BotController extends BaseCurdController<BotService, Bot> {
}
private ChatRuntimeContext buildRuntimeContext(Bot bot, BigInteger conversationId, String prompt, List<String> attachments) {
LoginAccount account = SaTokenUtil.getLoginAccount();
LoginAccount account = requireCurrentLoginAccount();
ChatRuntimeContext context = new ChatRuntimeContext();
context.setChannel(ChatChannel.ADMIN);
context.setSessionId(conversationId);
context.setTenantId(account == null ? BigInteger.ZERO : account.getTenantId());
context.setDeptId(account == null ? BigInteger.ZERO : account.getDeptId());
context.setUserId(account == null ? BigInteger.ZERO : account.getId());
context.setUserAccount(account == null ? "admin" : account.getLoginName());
context.setUserName(account == null ? "管理员" : (StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName()));
context.setTenantId(account.getTenantId());
context.setDeptId(account.getDeptId());
context.setUserId(account.getId());
context.setUserAccount(account.getLoginName());
context.setUserName(StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName());
context.setAssistantId(bot == null ? BigInteger.ZERO : bot.getId());
context.setAssistantCode(bot == null ? null : bot.getAlias());
context.setAssistantName(bot == null ? null : bot.getTitle());
context.setSessionTitle(prompt.length() > 200 ? prompt.substring(0, 200) : prompt);
context.setAttachments(attachments);
ChatTimeToolAvailabilityContext.bindLoggedInSnapshot(context, account, bot);
return context;
}
private LoginAccount requireCurrentLoginAccount() {
try {
return SaTokenUtil.getLoginAccount();
} catch (Exception e) {
throw new BusinessException("当前登录状态失效,请重新登录后再试");
}
}
@Override
protected Result<?> onRemoveBefore(Collection<Serializable> ids) {
QueryWrapper queryWrapperKnowledge = QueryWrapper.create().in(BotDocumentCollection::getBotId, ids);

View File

@@ -17,6 +17,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import tech.easyflow.ai.chattime.availability.ChatTimeToolAvailabilityContext;
import tech.easyflow.ai.entity.*;
import tech.easyflow.ai.service.*;
import tech.easyflow.ai.service.impl.BotServiceImpl;
@@ -287,24 +288,33 @@ public class UcBotController extends BaseCurdController<BotService, Bot> {
}
private ChatRuntimeContext buildRuntimeContext(Bot bot, BigInteger conversationId, String prompt, List<String> attachments) {
LoginAccount account = SaTokenUtil.getLoginAccount();
LoginAccount account = requireCurrentLoginAccount();
ChatRuntimeContext context = new ChatRuntimeContext();
context.setChannel(ChatChannel.USER_CENTER);
context.setSessionId(conversationId);
context.setTenantId(account == null ? BigInteger.ZERO : account.getTenantId());
context.setDeptId(account == null ? BigInteger.ZERO : account.getDeptId());
context.setUserId(account == null ? BigInteger.ZERO : account.getId());
context.setUserAccount(account == null ? "anonymous" : account.getLoginName());
context.setUserName(account == null ? "匿名用户" : (StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName()));
context.setTenantId(account.getTenantId());
context.setDeptId(account.getDeptId());
context.setUserId(account.getId());
context.setUserAccount(account.getLoginName());
context.setUserName(StringUtils.hasText(account.getNickname()) ? account.getNickname() : account.getLoginName());
context.setAssistantId(bot == null ? BigInteger.ZERO : bot.getId());
context.setAssistantCode(bot == null ? null : bot.getAlias());
context.setAssistantName(bot == null ? null : bot.getTitle());
context.setSessionTitle(prompt.length() > 200 ? prompt.substring(0, 200) : prompt);
context.setAnonymous(account == null || BigInteger.ZERO.equals(account.getId()));
context.setAnonymous(false);
context.setAttachments(attachments);
ChatTimeToolAvailabilityContext.bindLoggedInSnapshot(context, account, bot);
return context;
}
private LoginAccount requireCurrentLoginAccount() {
try {
return SaTokenUtil.getLoginAccount();
} catch (Exception e) {
throw new BusinessException("当前登录状态失效,请重新登录后再试");
}
}
private Map<String, Object> getDefaultLlmOptions() {
Map<String, Object> defaultLlmOptions = new HashMap<>();
defaultLlmOptions.put("temperature", 0.7);