Commit 8f0c5998aad17f50faca1ae857616c98e1bc47f6

Authored by cherishsince
1 parent f0e4e535

【解决todo】Chat Stream 处理失败的逻辑

yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
... ... @@ -32,6 +32,7 @@ public interface ErrorCodeConstants {
32 32  
33 33 // ========== API 聊天消息 1-040-004-000 ==========
34 34 ErrorCode AI_CHAT_MESSAGE_NOT_EXIST = new ErrorCode(1_040_004_000, "消息不存在!");
  35 + ErrorCode AI_CHAT_STREAM_ERROR = new ErrorCode(1_040_004_001, "Stream 对话异常!");
35 36  
36 37 // midjourney
37 38  
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.java
... ... @@ -58,7 +58,7 @@ public class AiChatMessageController {
58 58 @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快")
59 59 @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
60 60 @PermitAll // 解决 SSE 最终响应的时候,会被 Access Denied 拦截的问题
61   - public Flux<AiChatMessageSendRespVO> sendChatMessageStream(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) {
  61 + public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) {
62 62 return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId());
63 63 }
64 64  
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageService.java
1 1 package cn.iocoder.yudao.module.ai.service.chat;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
3 4 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.*;
4 5 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
5 6 import reactor.core.publisher.Flux;
... ... @@ -28,7 +29,7 @@ public interface AiChatMessageService {
28 29 * @param userId 用户编号
29 30 * @return 发送结果
30 31 */
31   - Flux<AiChatMessageSendRespVO> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId);
  32 + Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId);
32 33  
33 34 /**
34 35 * 获得指定会话的消息列表
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/chat/AiChatMessageServiceImpl.java
... ... @@ -5,13 +5,17 @@ import cn.hutool.core.util.ObjUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
7 7 import cn.iocoder.yudao.framework.ai.core.factory.AiClientFactory;
  8 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  9 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
8 10 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  11 +import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
9 12 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
10 13 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
11 14 import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
12 15 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
13 16 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
14 17 import jakarta.annotation.Resource;
  18 +import org.reactivestreams.Publisher;
15 19 import org.springframework.ai.chat.ChatResponse;
16 20 import org.springframework.ai.chat.StreamingChatClient;
17 21 import org.springframework.ai.chat.messages.*;
... ... @@ -107,7 +111,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
107 111 }
108 112  
109 113 @Override
110   - public Flux<AiChatMessageSendRespVO> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId) {
  114 + public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId) {
111 115 // 1.1 校验对话存在
112 116 AiChatConversationDO conversation = chatConversationService.validateExists(sendReqVO.getConversationId());
113 117 if (ObjUtil.notEqual(conversation.getUserId(), userId)) {
... ... @@ -145,12 +149,14 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
145 149 o -> o.setUserAvatar(user.getAvatar()));
146 150 AiChatMessageSendRespVO.Message receive = BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class,
147 151 o -> o.setRoleAvatar(role != null ? role.getAvatar() : null)).setContent(newContent);
148   - return new AiChatMessageSendRespVO().setSend(send).setReceive(receive);
  152 + return CommonResult.success(new AiChatMessageSendRespVO().setSend(send).setReceive(receive));
149 153 }).doOnComplete(() -> {
150 154 chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(contentBuffer.toString()));
151 155 }).doOnError(throwable -> {
152 156 log.error("[sendChatMessageStream][userId({}) sendReqVO({}) 发生异常]", userId, sendReqVO, throwable);
153 157 chatMessageMapper.updateById(new AiChatMessageDO().setId(assistantMessage.getId()).setContent(throwable.getMessage()));
  158 + }).onErrorResume( error -> {
  159 + return Flux.just(CommonResult.error(ErrorCodeConstants.AI_CHAT_STREAM_ERROR));
154 160 });
155 161 }
156 162  
... ...