| | |
| | | package cc.mrbird.febs.yinhe.service.impl; |
| | | |
| | | import cc.mrbird.febs.ai.res.product.ApiProductVo; |
| | | import cc.mrbird.febs.ai.strategy.LlmStrategyFactory; |
| | | import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum; |
| | | import cc.mrbird.febs.ai.utils.UUID; |
| | | import cc.mrbird.febs.common.entity.FebsResponse; |
| | | import cc.mrbird.febs.common.exception.FebsException; |
| | | import cc.mrbird.febs.common.utils.AppContants; |
| | | import cc.mrbird.febs.common.utils.LoginUserUtil; |
| | | import cc.mrbird.febs.common.utils.RedisUtils; |
| | | import cc.mrbird.febs.common.utils.YHLoginUserUtil; |
| | | import cc.mrbird.febs.rabbit.producter.AgentProducer; |
| | | import cc.mrbird.febs.yinhe.entity.*; |
| | | import cc.mrbird.febs.yinhe.mapper.*; |
| | | import cc.mrbird.febs.yinhe.req.*; |
| | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.dashscope.common.Message; |
| | | import com.alibaba.dashscope.common.Role; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import reactor.core.publisher.Flux; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | @Slf4j |
| | |
| | | |
| | | private final YhAiMemberMapper yhAiMemberMapper; |
| | | private final YHAiCompanyMapper yhAiCompanyMapper; |
| | | private final YHAiBannerMapper yhAiBannerMapper; |
| | | private final YHAiLogoMapper yhAiLogoMapper; |
| | | |
| | | private final YHAiAgentCategoryMapper yhAiAgentCategoryMapper; |
| | | private final YHAiAgentMapper yhAiAgentMapper; |
| | | private final YHAiAgentStartQuestionMapper yhAiAgentStartQuestionMapper; |
| | | private final YHAiAgentKnowledgeMapper yhAiAgentKnowledgeMapper; |
| | | private final YHAiKnowledgeMapper yhAiKnowledgeMapper; |
| | | |
| | | private final YhSysAgentCategoryMapper yhSysAgentCategoryMapper; |
| | | private final YHSysAgentStartQuestionMapper yhSysAgentStartQuestionMapper; |
| | | private final YHSysAgentMapper yhSysAgentMapper; |
| | | private final YHSysCompanyLevelMapper yhSysCompanyLevelMapper; |
| | | |
| | | private final YHAiTalkMapper yhAiTalkMapper; |
| | | private final YHAiTalkItemMapper yhAiTalkItemMapper; |
| | | |
| | | private final RedisUtils redisUtils; |
| | | private final AgentProducer agentProducer; |
| | | |
| | | private final LlmStrategyFactory llmStrategyFactory; |
| | | |
| | | @Override |
| | | public FebsResponse memberInfo() { |
| | |
| | | LambdaQueryWrapper<YHAiAgentCategory> query = Wrappers.lambdaQuery(YHAiAgentCategory.class); |
| | | query.eq(YHAiAgentCategory::getCompanyId,companyId); |
| | | query.eq(YHAiAgentCategory::getState,1); |
| | | if (ObjectUtil.isNotEmpty(dto.getId())){ |
| | | query.eq(YHAiAgentCategory::getId,dto.getId()); |
| | | } |
| | | if (ObjectUtil.isNotEmpty(dto.getHotState())){ |
| | | query.eq(YHAiAgentCategory::getHotState,dto.getHotState()); |
| | | } |
| | |
| | | @Override |
| | | public FebsResponse agentInfo(YHAgentInitDto dto) { |
| | | |
| | | String companyId = YHLoginUserUtil.getLoginUser().getCompanyId(); |
| | | String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); |
| | | YHAgentInitVo yhAgentInitVo = new YHAgentInitVo(); |
| | | |
| | | String id = dto.getId(); |
| | |
| | | |
| | | LambdaQueryWrapper<YhSysAgentCategory> query = Wrappers.lambdaQuery(YhSysAgentCategory.class); |
| | | query.eq(YhSysAgentCategory::getState,1); |
| | | if (ObjectUtil.isNotEmpty(dto.getId())){ |
| | | query.eq(YhSysAgentCategory::getId,dto.getId()); |
| | | } |
| | | if (ObjectUtil.isNotEmpty(dto.getHotState())){ |
| | | query.eq(YhSysAgentCategory::getHotState,dto.getHotState()); |
| | | } |
| | |
| | | |
| | | @Override |
| | | public FebsResponse agentSysList(YHSysAgentDto dto) { |
| | | ArrayList<YHSysAgentVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<YHSysAgent> query = Wrappers.lambdaQuery(YHSysAgent.class); |
| | | query.eq(YHSysAgent::getState,1); |
| | | if (ObjectUtil.isNotEmpty(dto.getAgentCategoryId())){ |
| | | query.eq(YHSysAgent::getAgentCategoryId,dto.getAgentCategoryId()); |
| | | } |
| | | query.orderByDesc(YHSysAgent::getCreateTime); |
| | | |
| | | List<YHSysAgent> list = yhSysAgentMapper.selectList(query); |
| | | if (CollUtil.isNotEmpty(list)){ |
| | | |
| | | for (YHSysAgent entity : list) { |
| | | YHSysAgentVo vo = new YHSysAgentVo(); |
| | | vo.setId(entity.getId()); |
| | | vo.setName(entity.getName()); |
| | | vo.setDescription(entity.getDescription()); |
| | | vo.setIconImg(entity.getIconImg()); |
| | | vos.add(vo); |
| | | } |
| | | } |
| | | return new FebsResponse().success().data(vos); |
| | | // 创建分页对象,传入当前页和每页大小 |
| | | Page<YHSysAgentVo> page = new Page<>(dto.getPageNow(), dto.getPageSize()); |
| | | Page<YHSysAgentVo> pageListByQuery = yhSysAgentMapper.getPageListByQuery(page, dto); |
| | | return new FebsResponse().success().data(pageListByQuery); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public FebsResponse logout() { |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); |
| | | |
| | | String redisKey = AppContants.XCX_LOGIN_PREFIX + memberUuid; |
| | | String existToken = redisUtils.getString(redisKey); |
| | |
| | | redisUtils.del(AppContants.XCX_LOGIN_PREFIX + memberUuid); |
| | | return new FebsResponse().success().message("退出登录"); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse initSend(YHSendInitDto dto) { |
| | | String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); |
| | | |
| | | YHSendInitVo vo = new YHSendInitVo(); |
| | | |
| | | String agentId = dto.getId(); |
| | | //获取智能体信息 |
| | | YHAiAgent yhAiAgent = yhAiAgentMapper.selectById(agentId); |
| | | if (yhAiAgent == null) { |
| | | |
| | | throw new FebsException("智能体不存在"); |
| | | } |
| | | if (yhAiAgent.getState() != 1){ |
| | | |
| | | throw new FebsException("智能体未启用"); |
| | | } |
| | | String companyId = yhAiAgent.getCompanyId(); |
| | | /** |
| | | * 新增一个会话记录 |
| | | */ |
| | | YHAiTalk entity = new YHAiTalk(); |
| | | entity.setId(UUID.getSimpleUUIDString()); |
| | | entity.setCompanyId(companyId); |
| | | entity.setCustomerId(memberUuid); |
| | | entity.setAgentId(yhAiAgent.getId()); |
| | | entity.setType(2); |
| | | entity.setCreateTime(new Date()); |
| | | yhAiTalkMapper.insert(entity); |
| | | |
| | | vo.setTalkId(entity.getId()); |
| | | return new FebsResponse().success().data(vo); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse saveContext(YHSaveContextDto dto) { |
| | | String talkId = dto.getTalkId(); |
| | | String type = dto.getType(); |
| | | String content = dto.getContent(); |
| | | |
| | | YHAiTalk aiTalk = yhAiTalkMapper.selectById(talkId); |
| | | if (aiTalk == null) { |
| | | throw new FebsException("会话不存在"); |
| | | } |
| | | //保存会话记录 |
| | | YHAiTalkItem aiTalkItem = new YHAiTalkItem(); |
| | | aiTalkItem.setId(UUID.getSimpleUUIDString()); |
| | | aiTalkItem.setCompanyId(aiTalk.getCompanyId()); |
| | | aiTalkItem.setTalkId(aiTalk.getId()); |
| | | aiTalkItem.setType(type); |
| | | aiTalkItem.setContext(content); |
| | | aiTalkItem.setTokenNum(content.length()); |
| | | aiTalkItem.setCreateTime(new Date()); |
| | | yhAiTalkItemMapper.insert(aiTalkItem); |
| | | |
| | | agentProducer.sendAddCompanyToken(aiTalkItem.getId()); |
| | | return new FebsResponse().success(); |
| | | } |
| | | |
| | | @Override |
| | | public Flux<FebsResponse> aiAnswer(YHAitalkItemStreamDto dto) { |
| | | String talkId = dto.getTalkId(); |
| | | String reqContext = dto.getReqContext(); |
| | | |
| | | YHAiTalk aiTalk = yhAiTalkMapper.selectById(talkId); |
| | | if (aiTalk == null) { |
| | | throw new FebsException("会话不存在"); |
| | | } |
| | | |
| | | //获取智能体的信息 |
| | | String agentId = aiTalk.getAgentId(); |
| | | YHAiAgent aiAgent = yhAiAgentMapper.selectById(agentId); |
| | | if (aiAgent == null) { |
| | | throw new FebsException("智能体异常"); |
| | | } |
| | | //判断字符是否足够 |
| | | String companyId = aiTalk.getCompanyId(); |
| | | YHAiCompany aiCompany = yhAiCompanyMapper.selectById(companyId); |
| | | if (aiCompany == null) { |
| | | throw new FebsException("知识库异常"); |
| | | } |
| | | Integer useToken = aiCompany.getUseToken(); |
| | | YHSysCompanyLevel sysCompanyLevel = yhSysCompanyLevelMapper.selectOne( |
| | | Wrappers.lambdaQuery(YHSysCompanyLevel.class) |
| | | .select(YHSysCompanyLevel::getToken) |
| | | .eq(YHSysCompanyLevel::getCode, aiCompany.getLevelCode()) |
| | | ); |
| | | if (useToken > sysCompanyLevel.getToken()) { |
| | | throw new FebsException("字符已消耗完"); |
| | | } |
| | | //获取智能体绑定的知识库 |
| | | List<String> knowledgeIds = new ArrayList<>(); |
| | | String knowledgeId = aiCompany.getKnowledgeId(); |
| | | knowledgeIds.add(knowledgeId); |
| | | |
| | | //获取智能体绑定的查询文件 |
| | | List<String> fileIds = new ArrayList<>(); |
| | | List<YHAiAgentKnowledge> aiAgentKnowledges = yhAiAgentKnowledgeMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiAgentKnowledge.class) |
| | | .select(YHAiAgentKnowledge::getKnowledgeId) |
| | | .eq(YHAiAgentKnowledge::getAgentId, agentId) |
| | | .eq(YHAiAgentKnowledge::getCompanyId, companyId) |
| | | ); |
| | | if (CollUtil.isNotEmpty(aiAgentKnowledges)){ |
| | | List<String> aiKnowledgeIds = new ArrayList<>(); |
| | | for (YHAiAgentKnowledge aiAgentKnowledge : aiAgentKnowledges){ |
| | | aiKnowledgeIds.add(aiAgentKnowledge.getKnowledgeId()); |
| | | } |
| | | if (CollUtil.isNotEmpty(aiKnowledgeIds)){ |
| | | List<YHAiKnowledge> aiKnowledges = yhAiKnowledgeMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiKnowledge.class) |
| | | .select(YHAiKnowledge::getFileId) |
| | | .in(YHAiKnowledge::getId, aiKnowledgeIds) |
| | | ); |
| | | if (CollUtil.isNotEmpty(aiKnowledges)){ |
| | | for (YHAiKnowledge aiKnowledge : aiKnowledges){ |
| | | fileIds.add(aiKnowledge.getFileId()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | AiRequestDto aiRequestDto = new AiRequestDto(); |
| | | aiRequestDto.setTalkId(talkId); |
| | | String prompt = aiAgent.getPrompt(); |
| | | aiRequestDto.setRolePrompt(prompt); |
| | | // List<Message> messages = new ArrayList<>(); |
| | | // messages.add(Message.builder().role(Role.SYSTEM.getValue()).content(prompt).build()); |
| | | |
| | | //获取对话记录 |
| | | List<Message> messages = new ArrayList<>(); |
| | | List<YHAiTalkItem> aiTalkItemList = yhAiTalkItemMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiTalkItem.class) |
| | | .eq(YHAiTalkItem::getTalkId, talkId) |
| | | .orderByAsc(YHAiTalkItem::getCreateTime) |
| | | ); |
| | | if (CollUtil.isNotEmpty(aiTalkItemList)){ |
| | | messages = getMessages(messages,aiTalkItemList); |
| | | } |
| | | for ( |
| | | Message message : messages |
| | | ){ |
| | | log.info("上下文内容:{},{}", message.getRole(),message.getContent()); |
| | | } |
| | | aiRequestDto.setMessages(messages); |
| | | aiRequestDto.setKnowledgeIds(knowledgeIds); |
| | | aiRequestDto.setFileIds(fileIds); |
| | | aiRequestDto.setPrompt(reqContext); |
| | | aiRequestDto.setCompanyId(companyId); |
| | | //日志输出详细的请求参数的每一个属性 |
| | | log.info("请求参数:{}", aiRequestDto.getPrompt()); |
| | | log.info("请求参数:{}", aiRequestDto); |
| | | |
| | | |
| | | String modelName = LlmStrategyEnum.getName(2); |
| | | return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(aiRequestDto); |
| | | } |
| | | |
| | | private List<Message> getMessages(List<Message> messages,List<YHAiTalkItem> aiTalkItemList) { |
| | | for (YHAiTalkItem item : aiTalkItemList){ |
| | | if (StrUtil.equals(item.getType(), Role.USER.getValue())){ |
| | | messages.add(Message.builder() |
| | | .role(Role.USER.getValue()) |
| | | .content(item.getContext()) |
| | | .build()); |
| | | } |
| | | if (StrUtil.equals(item.getType(),Role.ASSISTANT.getValue())){ |
| | | messages.add(Message.builder() |
| | | .role(Role.ASSISTANT.getValue()) |
| | | .content(item.getContext()) |
| | | .build()); |
| | | } |
| | | } |
| | | return messages; |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse bannerList() { |
| | | List<YHBannerVo> vos = new ArrayList<>(); |
| | | List<YHAiBanner> list = yhAiBannerMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiBanner.class) |
| | | .eq(YHAiBanner::getState, 1) |
| | | .isNull(YHAiBanner::getCompanyId) |
| | | .orderByDesc(YHAiBanner::getSort) |
| | | ); |
| | | if (CollUtil.isNotEmpty(list)){ |
| | | for (YHAiBanner aiBanner : list){ |
| | | YHBannerVo vo = new YHBannerVo(); |
| | | vo.setName(aiBanner.getName()); |
| | | vo.setImageUrl(aiBanner.getImageUrl()); |
| | | vo.setSort(aiBanner.getSort()); |
| | | vos.add(vo); |
| | | } |
| | | } |
| | | return new FebsResponse().data(vos); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse logoInfo() { |
| | | YHLogoVo yhLogoVo = new YHLogoVo(); |
| | | |
| | | List<YHAiLogo> yhAiLogos = yhAiLogoMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiLogo.class) |
| | | .eq(YHAiLogo::getState, 1) |
| | | .isNull(YHAiLogo::getCompanyId) |
| | | ); |
| | | if (CollUtil.isNotEmpty(yhAiLogos)){ |
| | | YHAiLogo yhAiLogo = yhAiLogos.get(0); |
| | | yhLogoVo.setName(yhAiLogo.getName()); |
| | | yhLogoVo.setImageUrl(yhAiLogo.getImageUrl()); |
| | | yhLogoVo.setDesription(yhAiLogo.getDesription()); |
| | | } |
| | | |
| | | return new FebsResponse().data(yhLogoVo); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse loginBannerList() { |
| | | String companyId = YHLoginUserUtil.getLoginUser().getCompanyId(); |
| | | List<YHBannerVo> vos = new ArrayList<>(); |
| | | List<YHAiBanner> list = yhAiBannerMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiBanner.class) |
| | | .eq(YHAiBanner::getState, 1) |
| | | .eq(YHAiBanner::getCompanyId, companyId) |
| | | .isNull(YHAiBanner::getCompanyId) |
| | | .orderByDesc(YHAiBanner::getSort) |
| | | ); |
| | | if (CollUtil.isNotEmpty(list)){ |
| | | for (YHAiBanner aiBanner : list){ |
| | | YHBannerVo vo = new YHBannerVo(); |
| | | vo.setName(aiBanner.getName()); |
| | | vo.setImageUrl(aiBanner.getImageUrl()); |
| | | vo.setSort(aiBanner.getSort()); |
| | | vos.add(vo); |
| | | } |
| | | } |
| | | return new FebsResponse().data(vos); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse loginLogoInfo() { |
| | | String companyId = YHLoginUserUtil.getLoginUser().getCompanyId(); |
| | | YHLogoVo yhLogoVo = new YHLogoVo(); |
| | | |
| | | List<YHAiLogo> yhAiLogos = yhAiLogoMapper.selectList( |
| | | Wrappers.lambdaQuery(YHAiLogo.class) |
| | | .eq(YHAiLogo::getState, 1) |
| | | .eq(YHAiLogo::getCompanyId, companyId) |
| | | .isNull(YHAiLogo::getCompanyId) |
| | | ); |
| | | if (CollUtil.isNotEmpty(yhAiLogos)){ |
| | | YHAiLogo yhAiLogo = yhAiLogos.get(0); |
| | | yhLogoVo.setName(yhAiLogo.getName()); |
| | | yhLogoVo.setImageUrl(yhAiLogo.getImageUrl()); |
| | | yhLogoVo.setDesription(yhAiLogo.getDesription()); |
| | | } |
| | | |
| | | return new FebsResponse().data(yhLogoVo); |
| | | } |
| | | } |