Commit 708d66e8cf0647cb4c7afa2743794a478c8b9bce

Authored by cherishsince
1 parent bd3e6589

【测试】chat 聊天(send、send-stream)

yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/AiChatMessageController.java
@@ -30,7 +30,7 @@ public class AiChatMessageController { @@ -30,7 +30,7 @@ public class AiChatMessageController {
30 30
31 @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") 31 @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢")
32 @PostMapping("/send") 32 @PostMapping("/send")
33 - public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { 33 + public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) {
34 // TODO done @fan:使用 static import;这样就 success 就行了; 34 // TODO done @fan:使用 static import;这样就 success 就行了;
35 return success(chatService.chat(sendReqVO)); 35 return success(chatService.chat(sendReqVO));
36 } 36 }
@@ -39,7 +39,7 @@ public class AiChatMessageController { @@ -39,7 +39,7 @@ public class AiChatMessageController {
39 // TODO @fan:要不要使用 Flux 来返回;可以使用 Flux<AiChatMessageRespVO> 39 // TODO @fan:要不要使用 Flux 来返回;可以使用 Flux<AiChatMessageRespVO>
40 @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快") 40 @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快")
41 @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) 41 @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
42 - public SseEmitter sendMessageStream(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { 42 + public SseEmitter sendMessageStream(@Validated @RequestBody AiChatMessageSendReqVO sendReqVO) {
43 Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); 43 Utf8SseEmitter sseEmitter = new Utf8SseEmitter();
44 chatService.chatStream(sendReqVO, sseEmitter); 44 chatService.chatStream(sendReqVO, sseEmitter);
45 return sseEmitter; 45 return sseEmitter;
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatModalServiceImpl.java
@@ -97,7 +97,7 @@ public class AiChatModalServiceImpl implements AiChatModelService { @@ -97,7 +97,7 @@ public class AiChatModalServiceImpl implements AiChatModelService {
97 @Override 97 @Override
98 public void validateAvailable(AiChatModalRespVO chatModal) { 98 public void validateAvailable(AiChatModalRespVO chatModal) {
99 // 对话模型是否可用 99 // 对话模型是否可用
100 - if (CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) { 100 + if (!CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) {
101 throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED); 101 throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED);
102 } 102 }
103 } 103 }
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java
@@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
19 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; 19 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
20 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper; 20 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
21 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper; 21 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper;
22 -import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper;  
23 import cn.iocoder.yudao.module.ai.service.AiChatConversationService; 22 import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
24 import cn.iocoder.yudao.module.ai.service.AiChatModelService; 23 import cn.iocoder.yudao.module.ai.service.AiChatModelService;
25 import cn.iocoder.yudao.module.ai.service.AiChatRoleService; 24 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
@@ -48,7 +47,6 @@ import java.util.function.Consumer; @@ -48,7 +47,6 @@ import java.util.function.Consumer;
48 public class AiChatServiceImpl implements AiChatService { 47 public class AiChatServiceImpl implements AiChatService {
49 48
50 private final AiChatClientFactory aiChatClientFactory; 49 private final AiChatClientFactory aiChatClientFactory;
51 - private final AiChatRoleMapper aiChatRoleMapper;  
52 private final AiChatMessageMapper aiChatMessageMapper; 50 private final AiChatMessageMapper aiChatMessageMapper;
53 private final AiChatConversationMapper aiChatConversationMapper; 51 private final AiChatConversationMapper aiChatConversationMapper;
54 private final AiChatConversationService chatConversationService; 52 private final AiChatConversationService chatConversationService;
@@ -72,7 +70,7 @@ public class AiChatServiceImpl implements AiChatService { @@ -72,7 +70,7 @@ public class AiChatServiceImpl implements AiChatService {
72 // 校验角色是否公开 70 // 校验角色是否公开
73 aiChatRoleService.validateIsPublic(aiChatRoleDO); 71 aiChatRoleService.validateIsPublic(aiChatRoleDO);
74 // 获取 client 类型 72 // 获取 client 类型
75 - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getModel()); 73 + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
76 // 保存 chat message 74 // 保存 chat message
77 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(), 75 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
78 chatModal.getModel(), chatModal.getId(), req.getContent(), 76 chatModal.getModel(), chatModal.getId(), req.getContent(),
@@ -90,13 +88,12 @@ public class AiChatServiceImpl implements AiChatService { @@ -90,13 +88,12 @@ public class AiChatServiceImpl implements AiChatService {
90 ChatResponse call = chatClient.call(prompt); 88 ChatResponse call = chatClient.call(prompt);
91 content = call.getResult().getOutput().getContent(); 89 content = call.getResult().getOutput().getContent();
92 // 更新 conversation 90 // 更新 conversation
93 -  
94 } catch (Exception e) { 91 } catch (Exception e) {
95 content = ExceptionUtil.getMessage(e); 92 content = ExceptionUtil.getMessage(e);
96 } finally { 93 } finally {
97 // 保存 chat message 94 // 保存 chat message
98 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), 95 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
99 - chatModal.getModel(), chatModal.getId(), req.getContent(), 96 + chatModal.getModel(), chatModal.getId(), content,
100 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); 97 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
101 } 98 }
102 return new AiChatMessageRespVO().setContent(content); 99 return new AiChatMessageRespVO().setContent(content);
@@ -154,7 +151,7 @@ public class AiChatServiceImpl implements AiChatService { @@ -154,7 +151,7 @@ public class AiChatServiceImpl implements AiChatService {
154 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); 151 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
155 152
156 // 获取 client 类型 153 // 获取 client 类型
157 - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getModel()); 154 + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
158 StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum); 155 StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum);
159 Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt); 156 Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt);
160 157
@@ -166,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService { @@ -166,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService {
166 String content = chatResponse.getResults().get(0).getOutput().getContent(); 163 String content = chatResponse.getResults().get(0).getOutput().getContent();
167 try { 164 try {
168 contentBuffer.append(content); 165 contentBuffer.append(content);
169 - sseEmitter.send(content, MediaType.APPLICATION_JSON); 166 + sseEmitter.send(new AiChatMessageRespVO().setContent(content), MediaType.APPLICATION_JSON);
170 } catch (IOException e) { 167 } catch (IOException e) {
171 log.error("发送异常{}", ExceptionUtil.getMessage(e)); 168 log.error("发送异常{}", ExceptionUtil.getMessage(e));
172 // 如果不是因为关闭而抛出异常,则重新连接 169 // 如果不是因为关闭而抛出异常,则重新连接
@@ -183,7 +180,7 @@ public class AiChatServiceImpl implements AiChatService { @@ -183,7 +180,7 @@ public class AiChatServiceImpl implements AiChatService {
183 sseEmitter.complete(); 180 sseEmitter.complete();
184 // 保存 chat message 181 // 保存 chat message
185 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(), 182 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
186 - chatModal.getModel(), chatModal.getId(), req.getContent(), 183 + chatModal.getModel(), chatModal.getId(), contentBuffer.toString(),
187 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts()); 184 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
188 185
189 } 186 }
yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-message.http
1 1
  2 +### chat call
  3 +POST {{baseUrl}}/admin-api/ai/chat/message/send
  4 +Content-Type: application/json
  5 +Authorization: {{token}}
  6 +
  7 +{
  8 + "conversationId": "1781604279872581649",
  9 + "content": "中国好看吗?"
  10 +}
  11 +
  12 +
  13 +### chat call
  14 +POST {{baseUrl}}/admin-api/ai/chat/message/send-stream
  15 +Content-Type: application/json
  16 +Authorization: {{token}}
  17 +
  18 +{
  19 + "conversationId": "1781604279872581649",
  20 + "content": "苹果是什么颜色?"
  21 +}
  22 +
2 23
3 ### message list 24 ### message list
4 -GET {{baseUrl}}/ai/chat/message/list?chatConversationId=1781604279872581644 25 +GET {{baseUrl}}/admin-api/ai/chat/message/list-by-conversation-id?conversationId=1781604279872581649
5 Authorization: {{token}} 26 Authorization: {{token}}
6 27
7 28
8 ### message delete 29 ### message delete
9 -DELETE {{baseUrl}}/ai/chat/message/1781604279872581644/8 30 +DELETE {{baseUrl}}/admin-api/ai/chat/message/delete?id=50
10 Authorization: {{token}} 31 Authorization: {{token}}
yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat.http deleted
1 -  
2 -  
3 -### 登录  
4 -  
5 -POST {{baseUrl}}/admin-api/system/auth/login  
6 -Content-Type: application/json  
7 -tenant-id: 1  
8 -  
9 -{  
10 - "username": "admin",  
11 - "password": "123456",  
12 - "captchaVerification": "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==",  
13 - "socialCode": "1024",  
14 - "socialState": "9b2ffbc1-7425-4155-9894-9d5c08541d62",  
15 - "socialCodeValid": true  
16 -}  
17 -  
18 -### chat call  
19 -GET {{baseUrl}}/ai/chat?modal=qianwen&conversationId=1781604279872581644&prompt=中国好看吗?  
20 -Authorization: {{token}}  
21 -  
22 -  
23 -  
24 -### chat call  
25 -GET {{baseUrl}}/ai/chatStream?conversationId=1781604279872581644&prompt=苹果是什么颜色?&modal=yiYan3_5_8k  
26 -Authorization: {{token}}  
27 -  
28 -  
29 -  
30 -