send-stream

This commit is contained in:
wing
2025-11-22 16:55:05 +08:00
parent cc8e503f49
commit d03b87446b
10 changed files with 15 additions and 79 deletions

View File

@@ -257,7 +257,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService {
reasoningContentBuffer.append(newReasoningContent);
}
return success(new AiChatMessageSendRespVO()
.setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class))
//.setSend(BeanUtils.toBean(userMessage, AiChatMessageSendRespVO.Message.class))
.setReceive(BeanUtils.toBean(assistantMessage, AiChatMessageSendRespVO.Message.class)
.setContent(StrUtil.nullToDefault(newContent, "")) // 避免 null 的 情况
.setReasoningContent(StrUtil.nullToDefault(newReasoningContent, "")) // 避免 null 的 情况

View File

@@ -1,11 +1,11 @@
package cn.iocoder.yudao.module.tik.chat.controller.app;
package cn.iocoder.yudao.module.tik.chat.controller;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatConversationCreateMyReqVO;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatConversationRespVO;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatConversationUpdateMyReqVO;
import cn.iocoder.yudao.module.tik.chat.vo.AppAiChatConversationCreateMyReqVO;
import cn.iocoder.yudao.module.tik.chat.vo.AppAiChatConversationRespVO;
import cn.iocoder.yudao.module.tik.chat.vo.AppAiChatConversationUpdateMyReqVO;
import cn.iocoder.yudao.module.tik.controller.admin.chat.vo.conversation.AiChatConversationCreateMyReqVO;
import cn.iocoder.yudao.module.tik.controller.admin.chat.vo.conversation.AiChatConversationUpdateMyReqVO;
import cn.iocoder.yudao.module.tik.dal.dataobject.chat.AiChatConversationDO;

View File

@@ -1,12 +1,10 @@
package cn.iocoder.yudao.module.tik.chat.controller.app;
package cn.iocoder.yudao.module.tik.chat.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatMessageRespVO;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatMessageSendReqVO;
import cn.iocoder.yudao.module.tik.chat.vo.app.AppAiChatMessageSendRespVO;
import cn.iocoder.yudao.module.tik.chat.vo.AppAiChatMessageRespVO;
import cn.iocoder.yudao.module.tik.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
import cn.iocoder.yudao.module.tik.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
import cn.iocoder.yudao.module.tik.dal.dataobject.chat.AiChatConversationDO;
@@ -52,68 +50,6 @@ public class AppAiChatMessageController {
@Resource
private AiKnowledgeDocumentService knowledgeDocumentService;
@Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢")
@PostMapping("/send")
public CommonResult<AppAiChatMessageSendRespVO> sendMessage(@Valid @RequestBody AppAiChatMessageSendReqVO sendReqVO) {
// App VO 转换为 Admin VO
AiChatMessageSendReqVO adminReqVO = BeanUtils.toBean(sendReqVO, AiChatMessageSendReqVO.class);
// 调用 Service然后转换响应
var adminResp = chatMessageService.sendMessage(adminReqVO, getLoginUserId());
// 手动转换 segments因为内部类类型不同
AppAiChatMessageSendRespVO appResp = convertSendRespVO(adminResp);
return success(appResp);
}
/**
* Admin SendRespVO 转换为 App SendRespVO
* 主要处理 segments 字段的类型转换
*/
private AppAiChatMessageSendRespVO convertSendRespVO(cn.iocoder.yudao.module.tik.controller.admin.chat.vo.message.AiChatMessageSendRespVO adminResp) {
if (adminResp == null) {
return null;
}
AppAiChatMessageSendRespVO appResp = new AppAiChatMessageSendRespVO();
// 转换 send
if (adminResp.getSend() != null) {
AppAiChatMessageSendRespVO.Message appSend = BeanUtils.toBean(adminResp.getSend(), AppAiChatMessageSendRespVO.Message.class);
if (adminResp.getSend().getSegments() != null) {
appSend.setSegments(convertKnowledgeSegments(adminResp.getSend().getSegments()));
}
appResp.setSend(appSend);
}
// 转换 receive
if (adminResp.getReceive() != null) {
AppAiChatMessageSendRespVO.Message appReceive = BeanUtils.toBean(adminResp.getReceive(), AppAiChatMessageSendRespVO.Message.class);
if (adminResp.getReceive().getSegments() != null) {
appReceive.setSegments(convertKnowledgeSegments(adminResp.getReceive().getSegments()));
}
appResp.setReceive(appReceive);
}
return appResp;
}
/**
* 转换 KnowledgeSegment 列表
*/
private List<AppAiChatMessageSendRespVO.KnowledgeSegment> convertKnowledgeSegments(
List<cn.iocoder.yudao.module.tik.controller.admin.chat.vo.message.AiChatMessageRespVO.KnowledgeSegment> adminSegments) {
if (adminSegments == null) {
return null;
}
return convertList(adminSegments, segment -> {
if (segment == null) {
return null;
}
return new AppAiChatMessageSendRespVO.KnowledgeSegment()
.setId(segment.getId())
.setContent(segment.getContent())
.setDocumentId(segment.getDocumentId())
.setDocumentName(segment.getDocumentName());
});
}
@Operation(summary = "发送消息(流式)", description = "流式返回,响应较快")
@PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import cn.iocoder.yudao.module.tik.dal.dataobject.model.AiChatRoleDO;
import cn.iocoder.yudao.module.tik.dal.dataobject.model.AiModelDO;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import cn.iocoder.yudao.module.tik.framework.ai.core.webserch.AiWebSearchResponse;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;

View File

@@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.tik.chat.vo.app;
package cn.iocoder.yudao.module.tik.chat.vo;
import cn.iocoder.yudao.module.tik.framework.ai.core.webserch.AiWebSearchResponse;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@@ -36,7 +36,7 @@ public class BatchProduceAlignment {
private final String accessKeySecret = "kDqlGeJTKw6tJtFYiaY8vQTFuVIQDs";
public static void main(String[] args) {
/*public static void main(String[] args) {
try {
BatchProduceAlignment batchProduce = new BatchProduceAlignment();
batchProduce.initClient();
@@ -78,7 +78,7 @@ public class BatchProduceAlignment {
} catch (Exception e) {
System.out.println("Produce failed. Exception: " + e.toString());
}
}
}*/
public void initClient() throws Exception {