mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 17:21:53 +08:00
【调整】根据接口设计调整,ai model
This commit is contained in:
parent
118158424b
commit
c21b5f7679
@ -11,24 +11,27 @@ public interface ErrorCodeConstants {
|
|||||||
|
|
||||||
// ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ==========
|
// ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ==========
|
||||||
|
|
||||||
// TODO @fansili:1)类注释不太对;2)中英文之间,有个空格;例如说 AI 模型
|
// chat
|
||||||
ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI模型暂不支持!");
|
|
||||||
|
|
||||||
|
ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI 模型暂不支持!");
|
||||||
ErrorCode AI_CHAT_ROLE_NOT_EXISTENT = new ErrorCode(1_022_000_001, "AI Role 不存在!");;
|
ErrorCode AI_CHAT_ROLE_NOT_EXISTENT = new ErrorCode(1_022_000_001, "AI Role 不存在!");;
|
||||||
|
ErrorCode AI_CHAT_CONTINUE_CONVERSATION_ID_NOT_NULL = new ErrorCode(1_022_000_002, "chat 继续对话,对话 id 不能为空!");;
|
||||||
|
ErrorCode AI_CHAT_CONTINUE_NOT_EXIST = new ErrorCode(1_022_000_020, "chat 对话不存在!");
|
||||||
|
ErrorCode AI_CHAT_CONVERSATION_NOT_YOURS = new ErrorCode(1_022_000_021, "这条 chat 对话不是你的!");
|
||||||
|
|
||||||
|
// midjourney
|
||||||
ErrorCode AI_CHAT_CONTINUE_CONVERSATION_ID_NOT_NULL = new ErrorCode(1_022_000_002, "chat 继续对话,对话id不能为空!");;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ErrorCode AI_CHAT_CONTINUE_NOT_EXIST = new ErrorCode(1_022_000_020, "chat对话不存在!");
|
|
||||||
ErrorCode AI_CHAT_CONVERSATION_NOT_YOURS = new ErrorCode(1_022_000_021, "这条chat对话不是你的!");
|
|
||||||
|
|
||||||
ErrorCode AI_MIDJOURNEY_IMAGINE_FAIL = new ErrorCode(1_022_000_040, "midjourney imagine 操作失败!");
|
ErrorCode AI_MIDJOURNEY_IMAGINE_FAIL = new ErrorCode(1_022_000_040, "midjourney imagine 操作失败!");
|
||||||
|
|
||||||
ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "chatRole不存在!");
|
// role
|
||||||
|
|
||||||
ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "ai模型不存在!");
|
ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "chatRole 不存在!");
|
||||||
|
|
||||||
|
// modal
|
||||||
|
|
||||||
|
ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
|
||||||
|
ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
|
||||||
|
ErrorCode AI_MODAL_NOT_SUPPORTED_MODAL = new ErrorCode(1_022_000_082, "AI 模型不支持的 modal! {} ");
|
||||||
|
ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/6 11:48
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public enum AiChatModalTypeEnum {
|
||||||
|
}
|
@ -30,7 +30,7 @@ public class AiChatModalController {
|
|||||||
|
|
||||||
private final AiChatModalService aiChatModalService;
|
private final AiChatModalService aiChatModalService;
|
||||||
|
|
||||||
@Operation(summary = "ai模型 - 模型照片上传")
|
@Operation(summary = "ai模型 - 模型列表")
|
||||||
@GetMapping("/modal/list")
|
@GetMapping("/modal/list")
|
||||||
public PageResult<AiChatModalListRes> list(@ModelAttribute AiChatModalListReq req) {
|
public PageResult<AiChatModalListRes> list(@ModelAttribute AiChatModalListReq req) {
|
||||||
return aiChatModalService.list(req);
|
return aiChatModalService.list(req);
|
||||||
|
@ -22,27 +22,23 @@ public class AiChatModalDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
/**
|
||||||
* 模型key
|
* 名字
|
||||||
*/
|
*/
|
||||||
private String modelKey;
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 模型类型 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
|
* 类型
|
||||||
*/
|
|
||||||
private String modelPlatform;
|
|
||||||
/**
|
|
||||||
* 模型类型
|
|
||||||
* {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel}
|
* {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel}
|
||||||
* {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel}
|
* {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel}
|
||||||
*/
|
*/
|
||||||
private String modelType;
|
private String modal;
|
||||||
/**
|
/**
|
||||||
* 模型名字
|
* 平台 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
|
||||||
*/
|
*/
|
||||||
private String modelName;
|
private String platform;
|
||||||
/**
|
/**
|
||||||
* 模型照片
|
* 图片地址
|
||||||
*/
|
*/
|
||||||
private String modalImage;
|
private String imageUrl;
|
||||||
/**
|
/**
|
||||||
* 禁用 0、正常 1、禁用
|
* 禁用 0、正常 1、禁用
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.dal.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* chat config
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/6 15:06
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AiChatModalChatConfigVO extends AiChatModalConfigVO {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "在生成消息时采用的Top-K采样大小")
|
||||||
|
private Double topK;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "Top-P核采样方法的概率阈值")
|
||||||
|
private Double topP;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "温度参数,用于调整生成回复的随机性和多样性程度")
|
||||||
|
private Double temperature;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "最大 tokens")
|
||||||
|
private Integer maxTokens;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.dal.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* modal config
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/6 15:06
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AiChatModalConfigVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型平台 (冗余,方便类型转换)
|
||||||
|
* 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
|
||||||
|
*/
|
||||||
|
private String platform;
|
||||||
|
/**
|
||||||
|
* 模型类型(冗余,方便类型转换)
|
||||||
|
* {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel}
|
||||||
|
* {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel}
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.dal.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dall
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/6 15:06
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AiChatModalDallConfigVO extends AiChatModalConfigVO {
|
||||||
|
// 可选字段,默认为1
|
||||||
|
// 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。
|
||||||
|
private Integer n = 1;
|
||||||
|
|
||||||
|
// 可选字段,默认为standard
|
||||||
|
// 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。
|
||||||
|
private String quality = "standard";
|
||||||
|
|
||||||
|
// 可选字段,默认为url
|
||||||
|
// 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。
|
||||||
|
private String responseFormat = "url";
|
||||||
|
|
||||||
|
// 可选字段,默认为1024x1024
|
||||||
|
// 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。
|
||||||
|
private String size = "1024x1024";
|
||||||
|
|
||||||
|
// 可选字段,默认为vivid
|
||||||
|
// 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。
|
||||||
|
private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID;
|
||||||
|
|
||||||
|
// 可选字段
|
||||||
|
// 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。
|
||||||
|
private String endUserId = "UID123456";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package cn.iocoder.yudao.module.ai.dal.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Midjourney Config
|
||||||
|
*
|
||||||
|
* @author fansili
|
||||||
|
* @time 2024/5/6 15:07
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AiChatModalMidjourneyConfigVO extends AiChatModalConfigVO {
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
//package cn.iocoder.yudao.module.ai.mapper.typeHandler;
|
||||||
|
//
|
||||||
|
//import cn.hutool.core.util.StrUtil;
|
||||||
|
//import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||||
|
//import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
//import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
|
||||||
|
//import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
|
//import org.apache.ibatis.type.JdbcType;
|
||||||
|
//import org.apache.ibatis.type.MappedTypes;
|
||||||
|
//
|
||||||
|
//import java.sql.CallableStatement;
|
||||||
|
//import java.sql.PreparedStatement;
|
||||||
|
//import java.sql.ResultSet;
|
||||||
|
//import java.sql.SQLException;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * chat modal config
|
||||||
|
// *
|
||||||
|
// * @author fansili
|
||||||
|
// * @time 2024/5/6 11:18
|
||||||
|
// * @since 1.0
|
||||||
|
// */
|
||||||
|
//@MappedTypes(value = AiChatModalDO.Config.class)
|
||||||
|
//public class AiChatModelConfigTypeHandler extends BaseTypeHandler<AiChatModalDO.Config> {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void setNonNullParameter(PreparedStatement ps, int i, AiChatModalDO.Config parameter, JdbcType jdbcType) throws SQLException {
|
||||||
|
// // 将 MyCustomType 转换为数据库类型并设置到 PreparedStatement 中
|
||||||
|
// if (parameter == null) {
|
||||||
|
// ps.setString(i, "");
|
||||||
|
// } else {
|
||||||
|
// ps.setString(i, JsonUtils.toJsonString(parameter));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public AiChatModalDO.Config getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
|
||||||
|
// String str = rs.getString(columnName);
|
||||||
|
// if (StrUtil.isBlank(str)) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// AiChatModalDO.Config config = JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||||
|
// // 获取平台
|
||||||
|
// AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(config.getModelPlatform());
|
||||||
|
// if (AiPlatformEnum.CHAT_PLATFORM_LIST.contains(platformEnum)) {
|
||||||
|
// return JsonUtils.parseObject(str, AiChatModalDO.ChatConfig.class);
|
||||||
|
// } else if (AiPlatformEnum.OPEN_AI_DALL == platformEnum) {
|
||||||
|
// return JsonUtils.parseObject(str, AiChatModalDO.OpenAiImageConfig.class);
|
||||||
|
// } else if (AiPlatformEnum.MIDJOURNEY == platformEnum) {
|
||||||
|
// return JsonUtils.parseObject(str, AiChatModalDO.MidjourneyConfig.class);
|
||||||
|
// }
|
||||||
|
// throw new IllegalArgumentException("ai模型中config不能转换! json: " + str);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public AiChatModalDO.Config getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
|
// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
|
||||||
|
// String str = rs.getString(columnIndex);
|
||||||
|
// if (StrUtil.isBlank(str)) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public AiChatModalDO.Config getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
|
// // 从 CallableStatement 中获取数据库类型并转换为 MyCustomType
|
||||||
|
// String str = cs.getString(columnIndex);
|
||||||
|
// if (StrUtil.isBlank(str)) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
|
||||||
|
// }
|
||||||
|
//}
|
@ -1,23 +1,34 @@
|
|||||||
package cn.iocoder.yudao.module.ai.service.impl;
|
package cn.iocoder.yudao.module.ai.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.validation.ValidationUtil;
|
||||||
|
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||||
|
import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal;
|
||||||
|
import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
|
||||||
|
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
|
||||||
import cn.iocoder.yudao.module.ai.convert.AiChatModalConvert;
|
import cn.iocoder.yudao.module.ai.convert.AiChatModalConvert;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
|
||||||
|
import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalChatConfigVO;
|
||||||
|
import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalConfigVO;
|
||||||
|
import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalDallConfigVO;
|
||||||
import cn.iocoder.yudao.module.ai.enums.AiChatModalDisableEnum;
|
import cn.iocoder.yudao.module.ai.enums.AiChatModalDisableEnum;
|
||||||
import cn.iocoder.yudao.module.ai.mapper.AiChatModalMapper;
|
import cn.iocoder.yudao.module.ai.mapper.AiChatModalMapper;
|
||||||
import cn.iocoder.yudao.module.ai.service.AiChatModalService;
|
import cn.iocoder.yudao.module.ai.service.AiChatModalService;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
|
import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiChatModalListReq;
|
import cn.iocoder.yudao.module.ai.vo.AiChatModalListReq;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
|
import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ai 模型
|
* ai 模型
|
||||||
@ -40,7 +51,7 @@ public class AiChatModalServiceImpl implements AiChatModalService {
|
|||||||
queryWrapperX.eq(AiChatModalDO::getDisable, AiChatModalDisableEnum.NO.getValue());
|
queryWrapperX.eq(AiChatModalDO::getDisable, AiChatModalDisableEnum.NO.getValue());
|
||||||
// search
|
// search
|
||||||
if (!StrUtil.isBlank(req.getSearch())) {
|
if (!StrUtil.isBlank(req.getSearch())) {
|
||||||
queryWrapperX.like(AiChatModalDO::getModelName, req.getSearch().trim());
|
queryWrapperX.like(AiChatModalDO::getName, req.getSearch().trim());
|
||||||
}
|
}
|
||||||
// 默认排序
|
// 默认排序
|
||||||
queryWrapperX.orderByDesc(AiChatModalDO::getId);
|
queryWrapperX.orderByDesc(AiChatModalDO::getId);
|
||||||
@ -53,21 +64,38 @@ public class AiChatModalServiceImpl implements AiChatModalService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(AiChatModalAddReq req) {
|
public void add(AiChatModalAddReq req) {
|
||||||
|
// 校验 platform、type
|
||||||
|
validatePlatform(req.getPlatform());
|
||||||
|
validateModal(req.getPlatform(), req.getModal());
|
||||||
|
// 转换config
|
||||||
|
AiChatModalConfigVO aiChatModalConfigVO = convertConfig(req);
|
||||||
|
// 校验 modal config
|
||||||
|
validateModalConfig(aiChatModalConfigVO);
|
||||||
// 转换 do
|
// 转换 do
|
||||||
AiChatModalDO insertChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
|
AiChatModalDO insertChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
|
||||||
//
|
// 设置默认属性
|
||||||
insertChatModalDO.setDisable(AiChatModalDisableEnum.NO.getValue());
|
insertChatModalDO.setDisable(AiChatModalDisableEnum.NO.getValue());
|
||||||
|
insertChatModalDO.setConfig(JsonUtils.toJsonString(aiChatModalConfigVO));
|
||||||
// 保存数据库
|
// 保存数据库
|
||||||
aiChatModalMapper.insert(insertChatModalDO);
|
aiChatModalMapper.insert(insertChatModalDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Long id, AiChatModalAddReq req) {
|
public void update(Long id, AiChatModalAddReq req) {
|
||||||
|
// 校验 platform、type
|
||||||
|
validatePlatform(req.getPlatform());
|
||||||
|
validateModal(req.getPlatform(), req.getModal());
|
||||||
|
// 转换config
|
||||||
|
AiChatModalConfigVO aiChatModalConfigVO = convertConfig(req);
|
||||||
|
// 校验 modal config
|
||||||
|
validateModalConfig(aiChatModalConfigVO);
|
||||||
|
|
||||||
// 校验模型是否存在
|
// 校验模型是否存在
|
||||||
validateChatModalExists(id);
|
validateChatModalExists(id);
|
||||||
// 转换 updateChatModalDO
|
// 转换 updateChatModalDO
|
||||||
AiChatModalDO updateChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
|
AiChatModalDO updateChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
|
||||||
updateChatModalDO.setId(id);
|
updateChatModalDO.setId(id);
|
||||||
|
updateChatModalDO.setConfig(JsonUtils.toJsonString(aiChatModalConfigVO));
|
||||||
// 更新数据库
|
// 更新数据库
|
||||||
aiChatModalMapper.updateById(updateChatModalDO);
|
aiChatModalMapper.updateById(updateChatModalDO);
|
||||||
}
|
}
|
||||||
@ -86,4 +114,52 @@ public class AiChatModalServiceImpl implements AiChatModalService {
|
|||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateModal(String platform, String modal) {
|
||||||
|
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(platform);
|
||||||
|
try {
|
||||||
|
if (AiPlatformEnum.QIAN_WEN == platformEnum) {
|
||||||
|
QianWenChatModal.valueOfModel(modal);
|
||||||
|
} else if (AiPlatformEnum.XING_HUO == platformEnum) {
|
||||||
|
XingHuoChatModel.valueOfModel(modal);
|
||||||
|
} else if (AiPlatformEnum.YI_YAN == platformEnum) {
|
||||||
|
YiYanChatModel.valueOfModel(modal);
|
||||||
|
} else {
|
||||||
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_SUPPORTED_MODAL, platform);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validatePlatform(String platform) {
|
||||||
|
try {
|
||||||
|
AiPlatformEnum.valueOfPlatform(platform);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_PLATFORM_PARAMS_INCORRECT, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateModalConfig(AiChatModalConfigVO aiChatModalConfigVO) {
|
||||||
|
Set<ConstraintViolation<AiChatModalConfigVO>> validate = ValidationUtil.validate(aiChatModalConfigVO);
|
||||||
|
for (ConstraintViolation<AiChatModalConfigVO> constraintViolation : validate) {
|
||||||
|
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, constraintViolation.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AiChatModalConfigVO convertConfig(AiChatModalAddReq req) {
|
||||||
|
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getPlatform());
|
||||||
|
AiChatModalConfigVO resVo = null;
|
||||||
|
if (AiPlatformEnum.CHAT_PLATFORM_LIST.contains(platformEnum)) {
|
||||||
|
resVo = JsonUtils.parseObject(JsonUtils.toJsonString(req.getConfig()), AiChatModalChatConfigVO.class);
|
||||||
|
} else if (AiPlatformEnum.OPEN_AI_DALL == platformEnum) {
|
||||||
|
resVo = JsonUtils.parseObject(JsonUtils.toJsonString(req.getConfig()), AiChatModalDallConfigVO.class);
|
||||||
|
}
|
||||||
|
if (resVo == null) {
|
||||||
|
throw new IllegalArgumentException("ai模型中config不能转换! json: " + req.getConfig());
|
||||||
|
}
|
||||||
|
resVo.setType(req.getModal());
|
||||||
|
resVo.setPlatform(req.getPlatform());
|
||||||
|
return resVo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import cn.iocoder.yudao.framework.ai.image.ImageGeneration;
|
|||||||
import cn.iocoder.yudao.framework.ai.image.ImagePrompt;
|
import cn.iocoder.yudao.framework.ai.image.ImagePrompt;
|
||||||
import cn.iocoder.yudao.framework.ai.image.ImageResponse;
|
import cn.iocoder.yudao.framework.ai.image.ImageResponse;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient;
|
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum;
|
import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageModelEnum;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions;
|
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum;
|
import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
|
||||||
import cn.iocoder.yudao.framework.ai.midjourney.api.MidjourneyInteractionsApi;
|
import cn.iocoder.yudao.framework.ai.midjourney.api.MidjourneyInteractionsApi;
|
||||||
import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MidjourneyWebSocketStarter;
|
import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MidjourneyWebSocketStarter;
|
||||||
import cn.iocoder.yudao.framework.ai.midjourney.webSocket.WssNotify;
|
import cn.iocoder.yudao.framework.ai.midjourney.webSocket.WssNotify;
|
||||||
@ -21,7 +21,6 @@ import cn.iocoder.yudao.module.ai.mapper.AiImageMapper;
|
|||||||
import cn.iocoder.yudao.module.ai.service.AiImageService;
|
import cn.iocoder.yudao.module.ai.service.AiImageService;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq;
|
import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiImageMidjourneyReq;
|
import cn.iocoder.yudao.module.ai.vo.AiImageMidjourneyReq;
|
||||||
import cn.iocoder.yudao.module.ai.vo.AiImageMidjourneyRes;
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -6,6 +6,8 @@ import jakarta.validation.constraints.Size;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ai chat modal
|
* ai chat modal
|
||||||
*
|
*
|
||||||
@ -19,18 +21,24 @@ public class AiChatModalAddReq {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Schema(description = "模型名字")
|
@Schema(description = "模型名字")
|
||||||
@Size(max = 60, message = "模型名字最大60")
|
@Size(max = 60, message = "模型名字最大60个字符")
|
||||||
private String modelName;
|
private String name;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Size(max = 32, message = "模型平台最大32个字符")
|
||||||
|
@Schema(description = "模型平台 参考 AiPlatformEnum")
|
||||||
|
private String platform;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
||||||
@Size(max = 32, message = "模型类型最大32")
|
@Size(max = 32, message = "模型类型最大32个字符")
|
||||||
private String modelType;
|
private String modal;
|
||||||
|
|
||||||
@Schema(description = "模型照片")
|
@Schema(description = "模型照片")
|
||||||
private String modalImage;
|
@Size(max = 256, message = "模型照片地址最大256个字符")
|
||||||
|
private String imageUrl;
|
||||||
|
|
||||||
@Schema(description = "模型配置JSON")
|
@Schema(description = "模型配置JSON")
|
||||||
private String modelConfig;
|
// @Size(max = 1024, message = "模型配置最大1024个字符")
|
||||||
|
private Map<String, Object> config;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.ai.vo;
|
package cn.iocoder.yudao.module.ai.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@ -13,29 +15,25 @@ import lombok.experimental.Accessors;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class AiChatModalListRes {
|
public class AiChatModalListRes {
|
||||||
/**
|
|
||||||
* 编号
|
@Schema(description = "id")
|
||||||
*/
|
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
|
||||||
* 模型名字
|
@Schema(description = "模型平台 参考 AiPlatformEnum")
|
||||||
*/
|
private String platform;
|
||||||
private String modelName;
|
|
||||||
/**
|
@Schema(description = "模型类型 参考 YiYanChatModel、XingHuoChatModel")
|
||||||
* 模型类型(qianwen、yiyan、xinghuo、openai)
|
private String modal;
|
||||||
*/
|
|
||||||
private String modelType;
|
@Schema(description = "模型名字")
|
||||||
/**
|
private String name;
|
||||||
* 模型照片
|
|
||||||
*/
|
@Schema(description = "模型照片")
|
||||||
private String modalImage;
|
private String image;
|
||||||
/**
|
|
||||||
* 模型配置JSON
|
@Schema(description = "禁用 0、正常 1、禁用")
|
||||||
*/
|
|
||||||
private String modelConfig;
|
|
||||||
/**
|
|
||||||
* 禁用 0、正常 1、禁用
|
|
||||||
*/
|
|
||||||
private Integer disable;
|
private Integer disable;
|
||||||
|
|
||||||
|
@Schema(description = "modal 配置")
|
||||||
|
private String config;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
### chat call
|
### chat call
|
||||||
GET {{baseUrl}}/ai/chat/modal/list
|
GET {{baseUrl}}/ai/chat/modal/list
|
||||||
Authorization: {{token}}
|
Authorization: {{token}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### chat call
|
### chat call
|
||||||
PUT {{baseUrl}}/ai/chat/modal
|
PUT {{baseUrl}}/ai/chat/modal
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Authorization: {{token}}
|
Authorization: {{token}}
|
||||||
|
|
||||||
{
|
{
|
||||||
"modelName": "小红书Ai写作大模型",
|
"name": "小红书Ai写作大模型-plus",
|
||||||
"modelType": "yiyan",
|
"modal": "ERNIE-3.5-8K",
|
||||||
"modalImage": "",
|
"platform": "yiyan",
|
||||||
"modelConfig": ""
|
"imageUrl": "",
|
||||||
|
"config": {
|
||||||
|
"topK": 0.6,
|
||||||
|
"topP": 0.6,
|
||||||
|
"temperature": 0.86,
|
||||||
|
"maxTokens": 2048
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### chat call
|
||||||
|
POST {{baseUrl}}/ai/chat/modal/7
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "小红书Ai写作大模型-plus",
|
||||||
|
"modal": "ERNIE-3.5-8K",
|
||||||
|
"platform": "yiyan",
|
||||||
|
"imageUrl": "",
|
||||||
|
"config": {
|
||||||
|
"topK": 0.6,
|
||||||
|
"topP": 0.6,
|
||||||
|
"temperature": 0.86,
|
||||||
|
"maxTokens": 2048
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package cn.iocoder.yudao.framework.ai;
|
package cn.iocoder.yudao.framework.ai;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ai 模型平台
|
* ai 模型平台
|
||||||
*
|
*
|
||||||
@ -17,12 +20,27 @@ public enum AiPlatformEnum {
|
|||||||
YI_YAN("yiyan", "一言"),
|
YI_YAN("yiyan", "一言"),
|
||||||
QIAN_WEN("qianwen", "千问"),
|
QIAN_WEN("qianwen", "千问"),
|
||||||
XING_HUO("xinghuo", "星火"),
|
XING_HUO("xinghuo", "星火"),
|
||||||
|
OPEN_AI("openai", "openAi"),
|
||||||
|
OPEN_AI_DALL("dall", "dall"),
|
||||||
|
MIDJOURNEY("midjourney", "midjourney"),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private String platform;
|
private String platform;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
public static List<AiPlatformEnum> CHAT_PLATFORM_LIST = Lists.newArrayList(
|
||||||
|
AiPlatformEnum.YI_YAN,
|
||||||
|
AiPlatformEnum.QIAN_WEN,
|
||||||
|
AiPlatformEnum.XING_HUO,
|
||||||
|
AiPlatformEnum.OPEN_AI
|
||||||
|
);
|
||||||
|
|
||||||
|
public static List<AiPlatformEnum> IMAGE_PLATFORM_LIST = Lists.newArrayList(
|
||||||
|
AiPlatformEnum.OPEN_AI_DALL,
|
||||||
|
AiPlatformEnum.MIDJOURNEY
|
||||||
|
);
|
||||||
|
|
||||||
public static AiPlatformEnum valueOfPlatform(String platform) {
|
public static AiPlatformEnum valueOfPlatform(String platform) {
|
||||||
for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
|
for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
|
||||||
if (itemEnum.getPlatform().equals(platform)) {
|
if (itemEnum.getPlatform().equals(platform)) {
|
||||||
|
@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.ai.config;
|
|||||||
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||||
import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
|
import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
|
||||||
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
|
import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum;
|
import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageModelEnum;
|
||||||
import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum;
|
import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
Loading…
Reference in New Issue
Block a user