Commit 82c57840 by 彭顺

feat: 4月11日需求修改

parent 68f10d90
File added
...@@ -10,4 +10,7 @@ public class AgentCreateReqVO { ...@@ -10,4 +10,7 @@ public class AgentCreateReqVO {
@Schema(description = "智能体编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") @Schema(description = "智能体编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Long roleId; private Long roleId;
@Schema(description = "第一条消息作为标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好")
private String firstMsg;
} }
package cn.iocoder.yudao.module.ai.controller.admin.agent.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - Agent FeedBack Request VO")
@Data
public class AgentFeedBackReqVO {
@Schema(description = "智能体编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32")
private Long roleId;
@Schema(description = "对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long conversationId;
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String messageId;
@Schema(description = "好反馈", example = "yes")
private String userGoodFeedback;
@Schema(description = "坏反馈", example = "回复效果差")
private String userBadFeedback;
}
...@@ -11,4 +11,10 @@ public class AgentMsgReqVO { ...@@ -11,4 +11,10 @@ public class AgentMsgReqVO {
@Schema(description = "对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @Schema(description = "对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long conversationId; private Long conversationId;
@Schema(description = "分页偏移", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Long offset;
@Schema(description = "分页大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Long pageSize;
} }
...@@ -20,6 +20,9 @@ public class AgentUsedRespVO { ...@@ -20,6 +20,9 @@ public class AgentUsedRespVO {
@Trans(type = TransType.SIMPLE, target = AiChatRoleDO.class, fields = {"name", "avatar"}, refs = {"roleName", "roleAvatar"}) @Trans(type = TransType.SIMPLE, target = AiChatRoleDO.class, fields = {"name", "avatar"}, refs = {"roleName", "roleAvatar"})
private Long roleId; private Long roleId;
@Schema(description = "对话标题", example = "你好")
private String title;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime; private LocalDateTime createTime;
...@@ -28,7 +31,7 @@ public class AgentUsedRespVO { ...@@ -28,7 +31,7 @@ public class AgentUsedRespVO {
@Schema(description = "智能体头像", example = "https://www.iocoder.cn/1.png") @Schema(description = "智能体头像", example = "https://www.iocoder.cn/1.png")
private String roleAvatar; private String roleAvatar;
@Schema(description = "智能体名字", example = "小黄") @Schema(description = "智能体名字", example = "政府PPT编制")
private String roleName; private String roleName;
} }
...@@ -8,10 +8,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; ...@@ -8,10 +8,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.*;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO; import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
...@@ -41,6 +38,8 @@ import java.net.MalformedURLException; ...@@ -41,6 +38,8 @@ import java.net.MalformedURLException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
...@@ -83,13 +82,23 @@ public class AiChatMessageController { ...@@ -83,13 +82,23 @@ public class AiChatMessageController {
public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(@Valid @RequestBody AiChatMessageSendReqVO sendReqVO) throws MalformedURLException { public Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(@Valid @RequestBody AiChatMessageSendReqVO sendReqVO) throws MalformedURLException {
// 禁用ruoyi的上下文能力 // 禁用ruoyi的上下文能力
sendReqVO.setUseContext(false); sendReqVO.setUseContext(false);
String originalUrl = sendReqVO.getFileUrl(); List<String> originalUrls = sendReqVO.getFileUrl();
if(originalUrl != null && originalUrl.contains("218.77.58.8")){ if (originalUrls != null) {
// 替换IP地址 for (int i = 0; i < originalUrls.size(); i++) {
String replacedUrl = originalUrl.replace("218.77.58.8", "192.168.252.71"); String originalUrl = originalUrls.get(i);
sendReqVO.setFileUrl(replacedUrl); if (originalUrl != null && originalUrl.contains("218.77.58.8")) {
// 替换IP地址
String replacedUrl = originalUrl.replace("218.77.58.8", "192.168.252.71");
originalUrls.set(i, replacedUrl); // 更新列表中的URL
}
}
sendReqVO.setFileUrl(originalUrls); // 将更新后的列表重新设置到sendReqVO中
} }
return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId()); // 如果 responseChatId 为 null,则随机初始化一个 id
if (sendReqVO.getResponseChatItemId() == null) {
sendReqVO.setResponseChatItemId(generateBase62UniqueId(20));
}
return chatMessageService.sendChatMessageStream(sendReqVO, getLoginUserId(), originalUrls);
} }
@Operation(summary = "获得指定对话的消息列表") @Operation(summary = "获得指定对话的消息列表")
...@@ -147,4 +156,37 @@ public class AiChatMessageController { ...@@ -147,4 +156,37 @@ public class AiChatMessageController {
return success(true); return success(true);
} }
@Operation(summary = "反馈", description = "反馈回复是否有用")
@PostMapping("/feedback")
@PreAuthorize("@ss.hasPermission('ai:chat-message:update')")
public CommonResult<Boolean> feedback(@Valid @RequestBody AiChatMessageFeedBackReqVO sendReqVO) {
chatMessageService.updateFeedback(sendReqVO);
return success(true);
}
private String generateBase62UniqueId(int length) {
// Base62 字符集(0-9, A-Z, a-z)
final String BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(length);
// 使用 UUID 作为随机源
UUID uuid = UUID.randomUUID();
long mostSignificantBits = uuid.getMostSignificantBits();
long leastSignificantBits = uuid.getLeastSignificantBits();
// 将 UUID 的 128 位数据转换为 Base62
for (int i = 0; i < length; i++) {
// 取随机位并映射到 Base62 字符集
long randomValue = ThreadLocalRandom.current().nextLong(62);
if (i < 11) {
randomValue = (mostSignificantBits >>> (i * 5)) & 0x3F; // 取 6 位
} else {
randomValue = (leastSignificantBits >>> ((i - 11) * 5)) & 0x3F; // 取 6 位
}
sb.append(BASE62.charAt((int) (randomValue % 62)));
}
return sb.toString();
}
} }
package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message;
import cn.iocoder.yudao.framework.ai.core.model.fastgpt.FastGPTOptions;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - AI 聊天消息反馈")
@Data
public class AiChatMessageFeedBackReqVO {
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "消息编号不能为空")
private Long id;
@Schema(description = "反馈内容", example = "回答不准确")
// @NotEmpty(message = "聊天内容不能为空")
private String fdContent;
@Schema(description = "是否有用", example = "true")
private Boolean useful;
}
...@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; ...@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - AI 聊天消息 Response VO") @Schema(description = "管理后台 - AI 聊天消息 Response VO")
@Data @Data
...@@ -47,4 +48,13 @@ public class AiChatMessageRespVO { ...@@ -47,4 +48,13 @@ public class AiChatMessageRespVO {
@Schema(description = "角色名字", example = "小黄") @Schema(description = "角色名字", example = "小黄")
private String roleName; private String roleName;
@Schema(description = "对话文件列表")
private List<String> fileUrls;
@Schema(description = "是否有用")
private Boolean useful;
@Schema(description = "反馈内容")
private String fdContent;
} }
...@@ -8,6 +8,8 @@ import jakarta.validation.constraints.Size; ...@@ -8,6 +8,8 @@ import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.List;
@Schema(description = "管理后台 - AI 聊天消息发送 Request VO") @Schema(description = "管理后台 - AI 聊天消息发送 Request VO")
@Data @Data
public class AiChatMessageSendReqVO { public class AiChatMessageSendReqVO {
...@@ -23,10 +25,15 @@ public class AiChatMessageSendReqVO { ...@@ -23,10 +25,15 @@ public class AiChatMessageSendReqVO {
@Schema(description = "是否携带上下文", example = "true") @Schema(description = "是否携带上下文", example = "true")
private Boolean useContext; private Boolean useContext;
// @Schema(description = "文件路径")
// private String fileUrl;
@Schema(description = "文件路径") @Schema(description = "文件路径")
private String fileUrl; private List<String> fileUrl;
@Schema(description = "变量") @Schema(description = "变量")
private FastGPTOptions.Variables variables; private FastGPTOptions.Variables variables;
@Schema(description = "回复信息预设ID")
private String responseChatItemId;
} }
...@@ -31,6 +31,9 @@ public class AiChatMessageSendRespVO { ...@@ -31,6 +31,9 @@ public class AiChatMessageSendRespVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private String chatItemId;
} }
} }
package cn.iocoder.yudao.module.ai.dal.dataobject.chat; package cn.iocoder.yudao.module.ai.dal.dataobject.chat;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import org.springframework.ai.chat.messages.MessageType; import org.springframework.ai.chat.messages.MessageType;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO; import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
...@@ -9,13 +11,15 @@ import com.baomidou.mybatisplus.annotation.KeySequence; ...@@ -9,13 +11,15 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*; import lombok.*;
import java.util.List;
/** /**
* AI Chat 消息 DO * AI Chat 消息 DO
* *
* @since 2024/4/14 17:35 * @since 2024/4/14 17:35
* @since 2024/4/14 17:35 * @since 2024/4/14 17:35
*/ */
@TableName("ai_chat_message") @TableName(value = "ai_chat_message", autoResultMap = true)
@KeySequence("ai_chat_conversation_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @KeySequence("ai_chat_conversation_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
...@@ -87,4 +91,20 @@ public class AiChatMessageDO extends BaseDO { ...@@ -87,4 +91,20 @@ public class AiChatMessageDO extends BaseDO {
*/ */
private Boolean useContext; private Boolean useContext;
/**
* 文件链接
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> fileUrls;
/**
* 是否有用
*/
private Boolean useful;
/**
* 反馈内容
*/
private String fdContent;
} }
...@@ -6,12 +6,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; ...@@ -6,12 +6,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationPageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -47,14 +48,31 @@ public interface AiChatMessageMapper extends BaseMapperX<AiChatMessageDO> { ...@@ -47,14 +48,31 @@ public interface AiChatMessageMapper extends BaseMapperX<AiChatMessageDO> {
record -> MapUtil.getInt(record, "count" )); record -> MapUtil.getInt(record, "count" ));
} }
default PageResult<AiChatMessageDO> selectPage(AiChatMessagePageReqVO pageReqVO) { // default PageResult<AiChatMessageDO> selectPage(AiChatMessagePageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<AiChatMessageDO>() // return selectPage(pageReqVO, new LambdaQueryWrapperX<AiChatMessageDO>()
.eqIfPresent(AiChatMessageDO::getConversationId, pageReqVO.getConversationId()) // .eqIfPresent(AiChatMessageDO::getConversationId, pageReqVO.getConversationId())
.eqIfPresent(AiChatMessageDO::getUserId, pageReqVO.getUserId()) // .eqIfPresent(AiChatMessageDO::getUserId, pageReqVO.getUserId())
.likeIfPresent(AiChatMessageDO::getContent, pageReqVO.getContent()) // .likeIfPresent(AiChatMessageDO::getContent, pageReqVO.getContent())
.betweenIfPresent(AiChatMessageDO::getCreateTime, pageReqVO.getCreateTime()) // .betweenIfPresent(AiChatMessageDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(AiChatMessageDO::getId)); // .orderByDesc(AiChatMessageDO::getId));
} // }
/**
* 分页查询,忽略逻辑删除的过滤条件
*/
@Select({
"<script>",
"SELECT * FROM ai_chat_message",
"<where>",
" <if test='req.conversationId != null'> AND conversation_id = #{req.conversationId} </if>",
" <if test='req.userId != null'> AND user_id = #{req.userId} </if>",
" <if test='req.content != null'> AND content LIKE CONCAT('%', #{req.content}, '%') </if>",
" <if test='req.createTime != null'> AND create_time BETWEEN #{req.createTime[0]} AND #{req.createTime[1]} </if>",
"</where>",
"ORDER BY id DESC",
"</script>"
})
IPage<AiChatMessageDO> selectPage(@Param("page") IPage<AiChatMessageDO> page, @Param("req") AiChatMessagePageReqVO pageReqVO);
default Long selectCounts(Long conId){ default Long selectCounts(Long conId){
return selectCount(new LambdaQueryWrapperX<AiChatMessageDO>() return selectCount(new LambdaQueryWrapperX<AiChatMessageDO>()
......
...@@ -169,17 +169,17 @@ public class AiChatConversationServiceImpl implements AiChatConversationService ...@@ -169,17 +169,17 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
Assert.notNull(model, "智能体未配置推理模型"); Assert.notNull(model, "智能体未配置推理模型");
validateChatModel(model); validateChatModel(model);
AiChatConversationDO conversationExist= chatConversationMapper.selectByRoleAndUserId(createReqVO.getRoleId(), userId); // AiChatConversationDO conversationExist= chatConversationMapper.selectByRoleAndUserId(createReqVO.getRoleId(), userId);
if(conversationExist != null){ // if(conversationExist != null){
return conversationExist.getId(); // return conversationExist.getId();
} // }
// 2. 创建 AiChatConversationDO 聊天对话 // 2. 创建 AiChatConversationDO 聊天对话
AiChatConversationDO conversation = new AiChatConversationDO().setUserId(userId).setPinned(false) AiChatConversationDO conversation = new AiChatConversationDO().setUserId(userId).setPinned(false)
.setModelId(model.getId()).setModel(model.getModel()) .setModelId(model.getId()).setModel(model.getModel())
.setTemperature(model.getTemperature()).setMaxTokens(model.getMaxTokens()).setMaxContexts(model.getMaxContexts()); .setTemperature(model.getTemperature()).setMaxTokens(model.getMaxTokens()).setMaxContexts(model.getMaxContexts());
if (role != null) { if (role != null) {
conversation.setTitle(role.getName()).setRoleId(role.getId()).setSystemMessage(role.getSystemMessage()); conversation.setTitle(createReqVO.getFirstMsg()).setRoleId(role.getId()).setSystemMessage(role.getSystemMessage());
} else { } else {
conversation.setTitle(AiChatConversationDO.TITLE_DEFAULT); conversation.setTitle(AiChatConversationDO.TITLE_DEFAULT);
} }
......
...@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.service.chat; ...@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.service.chat;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageFeedBackReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessagePageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO; import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendRespVO;
...@@ -36,7 +37,7 @@ public interface AiChatMessageService { ...@@ -36,7 +37,7 @@ public interface AiChatMessageService {
* @param userId 用户编号 * @param userId 用户编号
* @return 发送结果 * @return 发送结果
*/ */
Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId) throws MalformedURLException; Flux<CommonResult<AiChatMessageSendRespVO>> sendChatMessageStream(AiChatMessageSendReqVO sendReqVO, Long userId, List<String> originalUrls) throws MalformedURLException;
/** /**
* 获得指定对话的消息列表 * 获得指定对话的消息列表
...@@ -62,6 +63,8 @@ public interface AiChatMessageService { ...@@ -62,6 +63,8 @@ public interface AiChatMessageService {
*/ */
void deleteChatMessageByConversationId(Long conversationId, Long userId); void deleteChatMessageByConversationId(Long conversationId, Long userId);
boolean checkMsgExist(Long conversationId);
/** /**
* 【管理员】删除消息 * 【管理员】删除消息
* *
...@@ -85,4 +88,5 @@ public interface AiChatMessageService { ...@@ -85,4 +88,5 @@ public interface AiChatMessageService {
*/ */
PageResult<AiChatMessageDO> getChatMessagePage(AiChatMessagePageReqVO pageReqVO); PageResult<AiChatMessageDO> getChatMessagePage(AiChatMessagePageReqVO pageReqVO);
void updateFeedback(AiChatMessageFeedBackReqVO sendReqVO);
} }
...@@ -108,7 +108,7 @@ public class AiMindMapServiceImpl implements AiMindMapService { ...@@ -108,7 +108,7 @@ public class AiMindMapServiceImpl implements AiMindMapService {
List<Message> chatMessages = buildMessages(generateReqVO, systemMessage); List<Message> chatMessages = buildMessages(generateReqVO, systemMessage);
// 2. 构建 options 对象 // 2. 构建 options 对象
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform()); AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
ChatOptions options = AiUtils.buildChatOptions(platform, model.getModel(), model.getTemperature(), model.getMaxTokens(), "", null); ChatOptions options = AiUtils.buildChatOptions(platform, model.getModel(), model.getTemperature(), model.getMaxTokens(), "", null, "");
return new Prompt(chatMessages, options); return new Prompt(chatMessages, options);
} }
......
...@@ -126,7 +126,7 @@ public class AiWriteServiceImpl implements AiWriteService { ...@@ -126,7 +126,7 @@ public class AiWriteServiceImpl implements AiWriteService {
List<Message> chatMessages = buildMessages(generateReqVO, systemMessage); List<Message> chatMessages = buildMessages(generateReqVO, systemMessage);
// 2. 构建 options 对象 // 2. 构建 options 对象
AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform()); AiPlatformEnum platform = AiPlatformEnum.validatePlatform(model.getPlatform());
ChatOptions options = AiUtils.buildChatOptions(platform, model.getModel(), model.getTemperature(), model.getMaxTokens(), "", null); ChatOptions options = AiUtils.buildChatOptions(platform, model.getModel(), model.getTemperature(), model.getMaxTokens(), "", null, "");
return new Prompt(chatMessages, options); return new Prompt(chatMessages, options);
} }
......
...@@ -113,28 +113,28 @@ public class FastGPTApi { ...@@ -113,28 +113,28 @@ public class FastGPTApi {
} }
@JsonInclude(Include.NON_NULL) @JsonInclude(Include.NON_NULL)
public static record ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, String chatId, FastGPTOptions.Variables variables, Float frequencyPenalty, Map<String, Integer> logitBias, Boolean logprobs, Integer topLogprobs, Integer maxTokens, Integer n, Float presencePenalty, ResponseFormat responseFormat, Integer seed, List<String> stop, Boolean stream, Float temperature, Float topP, List<FunctionTool> tools, Object toolChoice, String user) { public static record ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, String chatId, FastGPTOptions.Variables variables, String responseChatItemId, Float frequencyPenalty, Map<String, Integer> logitBias, Boolean logprobs, Integer topLogprobs, Integer maxTokens, Integer n, Float presencePenalty, ResponseFormat responseFormat, Integer seed, List<String> stop, Boolean stream, Float temperature, Float topP, List<FunctionTool> tools, Object toolChoice, String user) {
public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, Float temperature) { public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, Float temperature) {
this(messages, model, (String)null, (FastGPTOptions.Variables)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, false, temperature, (Float)null, (List)null, (Object)null, (String)null); this(messages, model, (String)null, (FastGPTOptions.Variables)null, (String)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, false, temperature, (Float)null, (List)null, (Object)null, (String)null);
} }
public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, Float temperature, boolean stream) { public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, Float temperature, boolean stream) {
this(messages, model, (String)null, (FastGPTOptions.Variables)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, temperature, (Float)null, (List)null, (Object)null, (String)null); this(messages, model, (String)null, (FastGPTOptions.Variables)null, (String)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, temperature, (Float)null, (List)null, (Object)null, (String)null);
} }
public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, List<FunctionTool> tools, Object toolChoice) { public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, List<FunctionTool> tools, Object toolChoice) {
this(messages, model, (String)null, (FastGPTOptions.Variables)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, false, 0.8F, (Float)null, tools, toolChoice, (String)null); this(messages, model, (String)null, (FastGPTOptions.Variables)null, (String)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, false, 0.8F, (Float)null, tools, toolChoice, (String)null);
} }
public ChatCompletionRequest(List<ChatCompletionMessage> messages, Boolean stream) { public ChatCompletionRequest(List<ChatCompletionMessage> messages, Boolean stream) {
this(messages, (String)null, (String)null, (FastGPTOptions.Variables)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, (Float)null, (Float)null, (List)null, (Object)null, (String)null); this(messages, (String)null, (String)null, (FastGPTOptions.Variables)null, (String)null, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, (Float)null, (Float)null, (List)null, (Object)null, (String)null);
} }
public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, String chatId, FastGPTOptions.Variables variables, Boolean stream) { public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model, String chatId, FastGPTOptions.Variables variables, String responseChatItemId, Boolean stream) {
this(messages, model, chatId, variables, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, (Float)null, (Float)null, (List)null, (Object)null, (String)null); this(messages, model, chatId, variables, responseChatItemId, (Float)null, (Map)null, (Boolean)null, (Integer)null, (Integer)null, (Integer)null, (Float)null, (ResponseFormat)null, (Integer)null, (List)null, stream, (Float)null, (Float)null, (List)null, (Object)null, (String)null);
} }
public ChatCompletionRequest(@JsonProperty("messages") List<ChatCompletionMessage> messages, @JsonProperty("model") String model, @JsonProperty("chatId") String chatId, @JsonProperty("variables") FastGPTOptions.Variables variables, @JsonProperty("frequency_penalty") Float frequencyPenalty, @JsonProperty("logit_bias") Map<String, Integer> logitBias, @JsonProperty("logprobs") Boolean logprobs, @JsonProperty("top_logprobs") Integer topLogprobs, @JsonProperty("max_tokens") Integer maxTokens, @JsonProperty("n") Integer n, @JsonProperty("presence_penalty") Float presencePenalty, @JsonProperty("response_format") ResponseFormat responseFormat, @JsonProperty("seed") Integer seed, @JsonProperty("stop") List<String> stop, @JsonProperty("stream") Boolean stream, @JsonProperty("temperature") Float temperature, @JsonProperty("top_p") Float topP, @JsonProperty("tools") List<FunctionTool> tools, @JsonProperty("tool_choice") Object toolChoice, @JsonProperty("user") String user) { public ChatCompletionRequest(@JsonProperty("messages") List<ChatCompletionMessage> messages, @JsonProperty("model") String model, @JsonProperty("chatId") String chatId, @JsonProperty("variables") FastGPTOptions.Variables variables, @JsonProperty("responseChatItemId") String responseChatItemId, @JsonProperty("frequency_penalty") Float frequencyPenalty, @JsonProperty("logit_bias") Map<String, Integer> logitBias, @JsonProperty("logprobs") Boolean logprobs, @JsonProperty("top_logprobs") Integer topLogprobs, @JsonProperty("max_tokens") Integer maxTokens, @JsonProperty("n") Integer n, @JsonProperty("presence_penalty") Float presencePenalty, @JsonProperty("response_format") ResponseFormat responseFormat, @JsonProperty("seed") Integer seed, @JsonProperty("stop") List<String> stop, @JsonProperty("stream") Boolean stream, @JsonProperty("temperature") Float temperature, @JsonProperty("top_p") Float topP, @JsonProperty("tools") List<FunctionTool> tools, @JsonProperty("tool_choice") Object toolChoice, @JsonProperty("user") String user) {
this.messages = messages; this.messages = messages;
this.model = model; this.model = model;
this.chatId = chatId; this.chatId = chatId;
...@@ -155,6 +155,7 @@ public class FastGPTApi { ...@@ -155,6 +155,7 @@ public class FastGPTApi {
this.tools = tools; this.tools = tools;
this.toolChoice = toolChoice; this.toolChoice = toolChoice;
this.user = user; this.user = user;
this.responseChatItemId = responseChatItemId;
} }
@JsonProperty("messages") @JsonProperty("messages")
...@@ -177,6 +178,11 @@ public class FastGPTApi { ...@@ -177,6 +178,11 @@ public class FastGPTApi {
return this.variables; return this.variables;
} }
@JsonProperty("responseChatItemId")
public String responseChatItemId() {
return this.responseChatItemId;
}
@JsonProperty("frequency_penalty") @JsonProperty("frequency_penalty")
public Float frequencyPenalty() { public Float frequencyPenalty() {
return this.frequencyPenalty; return this.frequencyPenalty;
......
...@@ -164,7 +164,7 @@ public class FastGPTChatModel extends AbstractFunctionCallSupport<FastGPTApi.Cha ...@@ -164,7 +164,7 @@ public class FastGPTChatModel extends AbstractFunctionCallSupport<FastGPTApi.Cha
Set<String> promptEnabledFunctions = this.handleFunctionCallbackConfigurations(updatedRuntimeOptions, true); Set<String> promptEnabledFunctions = this.handleFunctionCallbackConfigurations(updatedRuntimeOptions, true);
functionsForThisRequest.addAll(promptEnabledFunctions); functionsForThisRequest.addAll(promptEnabledFunctions);
// request = (FastGPTApi.ChatCompletionRequest)ModelOptionsUtils.merge(updatedRuntimeOptions, request, FastGPTApi.ChatCompletionRequest.class); // request = (FastGPTApi.ChatCompletionRequest)ModelOptionsUtils.merge(updatedRuntimeOptions, request, FastGPTApi.ChatCompletionRequest.class);
request = new FastGPTApi.ChatCompletionRequest(chatCompletionMessages, updatedRuntimeOptions.getModel(), updatedRuntimeOptions.getChatId(), updatedRuntimeOptions.getVariables(), stream); request = new FastGPTApi.ChatCompletionRequest(chatCompletionMessages, updatedRuntimeOptions.getModel(), updatedRuntimeOptions.getChatId(), updatedRuntimeOptions.getVariables(), updatedRuntimeOptions.getResponseChatItemId(), stream);
} }
// if (this.defaultOptions != null) { // if (this.defaultOptions != null) {
......
...@@ -65,6 +65,9 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions { ...@@ -65,6 +65,9 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions {
@JsonIgnore @JsonIgnore
private Set<String> functions = new HashSet(); private Set<String> functions = new HashSet();
@JsonProperty("responseChatItemId")
private String responseChatItemId;
@JsonInclude(Include.NON_NULL) @JsonInclude(Include.NON_NULL)
public static record Variables(String scenarios) { public static record Variables(String scenarios) {
public Variables(@JsonProperty("scenarios") String scenarios) { public Variables(@JsonProperty("scenarios") String scenarios) {
...@@ -108,6 +111,14 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions { ...@@ -108,6 +111,14 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions {
this.chatId = chatId; this.chatId = chatId;
} }
public String getResponseChatItemId() {
return this.responseChatItemId;
}
public void setResponseChatItemId(String responseChatItemId) {
this.responseChatItemId = responseChatItemId;
}
public Float getFrequencyPenalty() { public Float getFrequencyPenalty() {
return this.frequencyPenalty; return this.frequencyPenalty;
} }
...@@ -249,6 +260,7 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions { ...@@ -249,6 +260,7 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions {
int result = 1; int result = 1;
result = 31 * result + (this.model == null ? 0 : this.model.hashCode()); result = 31 * result + (this.model == null ? 0 : this.model.hashCode());
result = 31 * result + (this.chatId == null ? 0 : this.chatId.hashCode()); result = 31 * result + (this.chatId == null ? 0 : this.chatId.hashCode());
result = 31 * result + (this.responseChatItemId == null ? 0 : this.responseChatItemId.hashCode());
result = 31 * result + (this.frequencyPenalty == null ? 0 : this.frequencyPenalty.hashCode()); result = 31 * result + (this.frequencyPenalty == null ? 0 : this.frequencyPenalty.hashCode());
result = 31 * result + (this.logitBias == null ? 0 : this.logitBias.hashCode()); result = 31 * result + (this.logitBias == null ? 0 : this.logitBias.hashCode());
result = 31 * result + (this.logprobs == null ? 0 : this.logprobs.hashCode()); result = 31 * result + (this.logprobs == null ? 0 : this.logprobs.hashCode());
...@@ -290,6 +302,13 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions { ...@@ -290,6 +302,13 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions {
} else if (!this.chatId.equals(other.chatId)) { } else if (!this.chatId.equals(other.chatId)) {
return false; return false;
} }
if (this.responseChatItemId == null) {
if (other.responseChatItemId != null) {
return false;
}
} else if (!this.responseChatItemId.equals(other.responseChatItemId)) {
return false;
}
if (this.frequencyPenalty == null) { if (this.frequencyPenalty == null) {
if (other.frequencyPenalty != null) { if (other.frequencyPenalty != null) {
...@@ -555,5 +574,10 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions { ...@@ -555,5 +574,10 @@ public class FastGPTOptions implements FunctionCallingOptions, ChatOptions {
public FastGPTOptions build() { public FastGPTOptions build() {
return this.options; return this.options;
} }
public Builder withChatItemId(String responseChatItemId) {
this.options.responseChatItemId = responseChatItemId;
return this;
}
} }
} }
...@@ -21,7 +21,7 @@ import org.springframework.ai.zhipuai.ZhiPuAiChatOptions; ...@@ -21,7 +21,7 @@ import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
*/ */
public class AiUtils { public class AiUtils {
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens, String chatId, FastGPTOptions.Variables variables) { public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens, String chatId, FastGPTOptions.Variables variables, String chatItemId) {
Float temperatureF = temperature != null ? temperature.floatValue() : null; Float temperatureF = temperature != null ? temperature.floatValue() : null;
//noinspection EnhancedSwitchMigration //noinspection EnhancedSwitchMigration
switch (platform) { switch (platform) {
...@@ -43,7 +43,7 @@ public class AiUtils { ...@@ -43,7 +43,7 @@ public class AiUtils {
case OLLAMA: case OLLAMA:
return OllamaOptions.create().withModel(model).withTemperature(temperatureF).withNumPredict(maxTokens); return OllamaOptions.create().withModel(model).withTemperature(temperatureF).withNumPredict(maxTokens);
case FAST_GPT: case FAST_GPT:
return FastGPTOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).withChatId(chatId).withVariables(variables).build(); return FastGPTOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).withChatId(chatId).withVariables(variables).withChatItemId(chatItemId).build();
default: default:
throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
} }
......
...@@ -75,6 +75,7 @@ mybatis-plus: ...@@ -75,6 +75,7 @@ mybatis-plus:
# id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解 # id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
logic-delete-field: deleted # 逻辑删除字段名
banner: false # 关闭控制台的 Banner 打印 banner: false # 关闭控制台的 Banner 打印
type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject
encryptor: encryptor:
......
...@@ -17,6 +17,8 @@ export interface ChatMessageVO { ...@@ -17,6 +17,8 @@ export interface ChatMessageVO {
createTime: Date // 创建时间 createTime: Date // 创建时间
roleAvatar: string // 角色头像 roleAvatar: string // 角色头像
userAvatar: string // 创建时间 userAvatar: string // 创建时间
useful: boolean // 是否有用
fdContent: boolean // 反馈内容
} }
// AI chat 聊天 // AI chat 聊天
......
...@@ -10,6 +10,8 @@ declare module 'vue' { ...@@ -10,6 +10,8 @@ declare module 'vue' {
AddNode: typeof import('./../components/SimpleProcessDesigner/src/addNode.vue')['default'] AddNode: typeof import('./../components/SimpleProcessDesigner/src/addNode.vue')['default']
AppLinkInput: typeof import('./../components/AppLinkInput/index.vue')['default'] AppLinkInput: typeof import('./../components/AppLinkInput/index.vue')['default']
AppLinkSelectDialog: typeof import('./../components/AppLinkInput/AppLinkSelectDialog.vue')['default'] AppLinkSelectDialog: typeof import('./../components/AppLinkInput/AppLinkSelectDialog.vue')['default']
'AutoComponents.d': typeof import('./auto-components.d.ts')['default']
'AutoImports.d': typeof import('./auto-imports.d.ts')['default']
Backtop: typeof import('./../components/Backtop/src/Backtop.vue')['default'] Backtop: typeof import('./../components/Backtop/src/Backtop.vue')['default']
CardTitle: typeof import('./../components/Card/src/CardTitle.vue')['default'] CardTitle: typeof import('./../components/Card/src/CardTitle.vue')['default']
ColorInput: typeof import('./../components/ColorInput/index.vue')['default'] ColorInput: typeof import('./../components/ColorInput/index.vue')['default']
......
...@@ -83,6 +83,12 @@ ...@@ -83,6 +83,12 @@
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.useContext" /> <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.useContext" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否有用" align="center" prop="useful" width="100">
<template #default="scope">
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.useful" />
</template>
</el-table-column>
<el-table-column label="反馈内容" align="center" prop="fdContent" width="300" />
<el-table-column label="操作" align="center" fixed="right"> <el-table-column label="操作" align="center" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button <el-button
......
...@@ -13,14 +13,14 @@ ...@@ -13,14 +13,14 @@
:on-exceed="handleExceed" :on-exceed="handleExceed"
:on-success="submitFormSuccess" :on-success="submitFormSuccess"
:http-request="httpRequest" :http-request="httpRequest"
accept=".jpg, .png, .gif" accept=""
drag drag
> >
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em></div> <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em></div>
<template #tip> <template #tip>
<div class="el-upload__tip" style="color: red"> <div class="el-upload__tip" style="color: red">
提示:仅允许导入 jpg、png、gif 格式文件 提示:文件大小低于64M
</div> </div>
</template> </template>
</el-upload> </el-upload>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment