Commit c21b5f76790e9cc05bfa0dd2545be057e96e1f94

Authored by cherishsince
1 parent 11815842

【调整】根据接口设计调整,ai model

Showing 16 changed files with 392 additions and 66 deletions
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
... ... @@ -11,24 +11,27 @@ public interface ErrorCodeConstants {
11 11  
12 12 // ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ==========
13 13  
14   - // TODO @fansili:1)类注释不太对;2)中英文之间,有个空格;例如说 AI 模型
15   - ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI模型暂不支持!");
  14 + // chat
16 15  
  16 + ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI 模型暂不支持!");
17 17 ErrorCode AI_CHAT_ROLE_NOT_EXISTENT = new ErrorCode(1_022_000_001, "AI Role 不存在!");;
  18 + ErrorCode AI_CHAT_CONTINUE_CONVERSATION_ID_NOT_NULL = new ErrorCode(1_022_000_002, "chat 继续对话,对话 id 不能为空!");;
  19 + ErrorCode AI_CHAT_CONTINUE_NOT_EXIST = new ErrorCode(1_022_000_020, "chat 对话不存在!");
  20 + ErrorCode AI_CHAT_CONVERSATION_NOT_YOURS = new ErrorCode(1_022_000_021, "这条 chat 对话不是你的!");
18 21  
19   -
20   - ErrorCode AI_CHAT_CONTINUE_CONVERSATION_ID_NOT_NULL = new ErrorCode(1_022_000_002, "chat 继续对话,对话id不能为空!");;
21   -
22   -
23   -
24   - ErrorCode AI_CHAT_CONTINUE_NOT_EXIST = new ErrorCode(1_022_000_020, "chat对话不存在!");
25   - ErrorCode AI_CHAT_CONVERSATION_NOT_YOURS = new ErrorCode(1_022_000_021, "这条chat对话不是你的!");
  22 + // midjourney
26 23  
27 24 ErrorCode AI_MIDJOURNEY_IMAGINE_FAIL = new ErrorCode(1_022_000_040, "midjourney imagine 操作失败!");
28 25  
29   - ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "chatRole不存在!");
  26 + // role
  27 +
  28 + ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "chatRole 不存在!");
30 29  
31   - ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "ai模型不存在!");
  30 + // modal
32 31  
  32 + ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
  33 + ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
  34 + ErrorCode AI_MODAL_NOT_SUPPORTED_MODAL = new ErrorCode(1_022_000_082, "AI 模型不支持的 modal! {} ");
  35 + ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
33 36  
34 37 }
... ...
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatModalTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.enums;
  2 +
  3 +/**
  4 + * 枚举
  5 + *
  6 + * @author fansili
  7 + * @time 2024/5/6 11:48
  8 + * @since 1.0
  9 + */
  10 +public enum AiChatModalTypeEnum {
  11 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/AiChatModalController.java
... ... @@ -30,7 +30,7 @@ public class AiChatModalController {
30 30  
31 31 private final AiChatModalService aiChatModalService;
32 32  
33   - @Operation(summary = "ai模型 - 模型照片上传")
  33 + @Operation(summary = "ai模型 - 模型列表")
34 34 @GetMapping("/modal/list")
35 35 public PageResult<AiChatModalListRes> list(@ModelAttribute AiChatModalListReq req) {
36 36 return aiChatModalService.list(req);
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/AiChatModalDO.java
... ... @@ -22,27 +22,23 @@ public class AiChatModalDO extends BaseDO {
22 22 */
23 23 private Long id;
24 24 /**
25   - * 模型key
  25 + * 名字
26 26 */
27   - private String modelKey;
  27 + private String name;
28 28 /**
29   - * 模型类型 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
30   - */
31   - private String modelPlatform;
32   - /**
33   - * 模型类型
  29 + * 类型
34 30 * {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel}
35 31 * {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel}
36 32 */
37   - private String modelType;
  33 + private String modal;
38 34 /**
39   - * 模型名字
  35 + * 平台 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
40 36 */
41   - private String modelName;
  37 + private String platform;
42 38 /**
43   - * 模型照片
  39 + * 图片地址
44 40 */
45   - private String modalImage;
  41 + private String imageUrl;
46 42 /**
47 43 * 禁用 0、正常 1、禁用
48 44 */
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalChatConfigVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.dal.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +import lombok.experimental.Accessors;
  7 +
  8 +/**
  9 + * chat config
  10 + *
  11 + * @author fansili
  12 + * @time 2024/5/6 15:06
  13 + * @since 1.0
  14 + */
  15 +@Data
  16 +@Accessors(chain = true)
  17 +public class AiChatModalChatConfigVO extends AiChatModalConfigVO {
  18 +
  19 + @NotNull
  20 + @Schema(description = "在生成消息时采用的Top-K采样大小")
  21 + private Double topK;
  22 +
  23 + @NotNull
  24 + @Schema(description = "Top-P核采样方法的概率阈值")
  25 + private Double topP;
  26 +
  27 + @NotNull
  28 + @Schema(description = "温度参数,用于调整生成回复的随机性和多样性程度")
  29 + private Double temperature;
  30 +
  31 + @NotNull
  32 + @Schema(description = "最大 tokens")
  33 + private Integer maxTokens;
  34 +
  35 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalConfigVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.dal.vo;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +/**
  7 + * modal config
  8 + *
  9 + * @author fansili
  10 + * @time 2024/5/6 15:06
  11 + * @since 1.0
  12 + */
  13 +@Data
  14 +@Accessors(chain = true)
  15 +public class AiChatModalConfigVO {
  16 +
  17 + /**
  18 + * 模型平台 (冗余,方便类型转换)
  19 + * 参考:{@link cn.iocoder.yudao.framework.ai.AiPlatformEnum}
  20 + */
  21 + private String platform;
  22 + /**
  23 + * 模型类型(冗余,方便类型转换)
  24 + * {@link cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel}
  25 + * {@link cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel}
  26 + */
  27 + private String type;
  28 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalDallConfigVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.dal.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
  4 +import lombok.Data;
  5 +import lombok.experimental.Accessors;
  6 +
  7 +/**
  8 + * dall
  9 + *
  10 + * @author fansili
  11 + * @time 2024/5/6 15:06
  12 + * @since 1.0
  13 + */
  14 +@Data
  15 +@Accessors(chain = true)
  16 +public class AiChatModalDallConfigVO extends AiChatModalConfigVO {
  17 + // 可选字段,默认为1
  18 + // 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。
  19 + private Integer n = 1;
  20 +
  21 + // 可选字段,默认为standard
  22 + // 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。
  23 + private String quality = "standard";
  24 +
  25 + // 可选字段,默认为url
  26 + // 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。
  27 + private String responseFormat = "url";
  28 +
  29 + // 可选字段,默认为1024x1024
  30 + // 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。
  31 + private String size = "1024x1024";
  32 +
  33 + // 可选字段,默认为vivid
  34 + // 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。
  35 + private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID;
  36 +
  37 + // 可选字段
  38 + // 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。
  39 + private String endUserId = "UID123456";
  40 +
  41 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalMidjourneyConfigVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.dal.vo;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +/**
  7 + * Midjourney Config
  8 + *
  9 + * @author fansili
  10 + * @time 2024/5/6 15:07
  11 + * @since 1.0
  12 + */
  13 +@Data
  14 +@Accessors(chain = true)
  15 +public class AiChatModalMidjourneyConfigVO extends AiChatModalConfigVO {
  16 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/mapper/typeHandler/AiChatModelConfigTypeHandler.java 0 → 100644
  1 +//package cn.iocoder.yudao.module.ai.mapper.typeHandler;
  2 +//
  3 +//import cn.hutool.core.util.StrUtil;
  4 +//import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
  5 +//import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  6 +//import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
  7 +//import org.apache.ibatis.type.BaseTypeHandler;
  8 +//import org.apache.ibatis.type.JdbcType;
  9 +//import org.apache.ibatis.type.MappedTypes;
  10 +//
  11 +//import java.sql.CallableStatement;
  12 +//import java.sql.PreparedStatement;
  13 +//import java.sql.ResultSet;
  14 +//import java.sql.SQLException;
  15 +//
  16 +///**
  17 +// * chat modal config
  18 +// *
  19 +// * @author fansili
  20 +// * @time 2024/5/6 11:18
  21 +// * @since 1.0
  22 +// */
  23 +//@MappedTypes(value = AiChatModalDO.Config.class)
  24 +//public class AiChatModelConfigTypeHandler extends BaseTypeHandler<AiChatModalDO.Config> {
  25 +//
  26 +// @Override
  27 +// public void setNonNullParameter(PreparedStatement ps, int i, AiChatModalDO.Config parameter, JdbcType jdbcType) throws SQLException {
  28 +// // 将 MyCustomType 转换为数据库类型并设置到 PreparedStatement 中
  29 +// if (parameter == null) {
  30 +// ps.setString(i, "");
  31 +// } else {
  32 +// ps.setString(i, JsonUtils.toJsonString(parameter));
  33 +// }
  34 +// }
  35 +//
  36 +// @Override
  37 +// public AiChatModalDO.Config getNullableResult(ResultSet rs, String columnName) throws SQLException {
  38 +// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
  39 +// String str = rs.getString(columnName);
  40 +// if (StrUtil.isBlank(str)) {
  41 +// return null;
  42 +// }
  43 +// AiChatModalDO.Config config = JsonUtils.parseObject(str, AiChatModalDO.Config.class);
  44 +// // 获取平台
  45 +// AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(config.getModelPlatform());
  46 +// if (AiPlatformEnum.CHAT_PLATFORM_LIST.contains(platformEnum)) {
  47 +// return JsonUtils.parseObject(str, AiChatModalDO.ChatConfig.class);
  48 +// } else if (AiPlatformEnum.OPEN_AI_DALL == platformEnum) {
  49 +// return JsonUtils.parseObject(str, AiChatModalDO.OpenAiImageConfig.class);
  50 +// } else if (AiPlatformEnum.MIDJOURNEY == platformEnum) {
  51 +// return JsonUtils.parseObject(str, AiChatModalDO.MidjourneyConfig.class);
  52 +// }
  53 +// throw new IllegalArgumentException("ai模型中config不能转换! json: " + str);
  54 +// }
  55 +//
  56 +// @Override
  57 +// public AiChatModalDO.Config getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  58 +// // 从 ResultSet 中获取数据库类型并转换为 MyCustomType
  59 +// String str = rs.getString(columnIndex);
  60 +// if (StrUtil.isBlank(str)) {
  61 +// return null;
  62 +// }
  63 +// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
  64 +// }
  65 +//
  66 +// @Override
  67 +// public AiChatModalDO.Config getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  68 +// // 从 CallableStatement 中获取数据库类型并转换为 MyCustomType
  69 +// String str = cs.getString(columnIndex);
  70 +// if (StrUtil.isBlank(str)) {
  71 +// return null;
  72 +// }
  73 +// return JsonUtils.parseObject(str, AiChatModalDO.Config.class);
  74 +// }
  75 +//}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatModalServiceImpl.java
1 1 package cn.iocoder.yudao.module.ai.service.impl;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.hutool.extra.validation.ValidationUtil;
  5 +import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
  6 +import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal;
  7 +import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
  8 +import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
4 9 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
5 10 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  11 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6 12 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 13 import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
8 14 import cn.iocoder.yudao.module.ai.convert.AiChatModalConvert;
9 15 import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
  16 +import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalChatConfigVO;
  17 +import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalConfigVO;
  18 +import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalDallConfigVO;
10 19 import cn.iocoder.yudao.module.ai.enums.AiChatModalDisableEnum;
11 20 import cn.iocoder.yudao.module.ai.mapper.AiChatModalMapper;
12 21 import cn.iocoder.yudao.module.ai.service.AiChatModalService;
13 22 import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
14 23 import cn.iocoder.yudao.module.ai.vo.AiChatModalListReq;
15 24 import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
  25 +import jakarta.validation.ConstraintViolation;
16 26 import lombok.AllArgsConstructor;
17 27 import lombok.extern.slf4j.Slf4j;
18 28 import org.springframework.stereotype.Service;
19 29  
20 30 import java.util.List;
  31 +import java.util.Set;
21 32  
22 33 /**
23 34 * ai 模型
... ... @@ -40,7 +51,7 @@ public class AiChatModalServiceImpl implements AiChatModalService {
40 51 queryWrapperX.eq(AiChatModalDO::getDisable, AiChatModalDisableEnum.NO.getValue());
41 52 // search
42 53 if (!StrUtil.isBlank(req.getSearch())) {
43   - queryWrapperX.like(AiChatModalDO::getModelName, req.getSearch().trim());
  54 + queryWrapperX.like(AiChatModalDO::getName, req.getSearch().trim());
44 55 }
45 56 // 默认排序
46 57 queryWrapperX.orderByDesc(AiChatModalDO::getId);
... ... @@ -53,21 +64,38 @@ public class AiChatModalServiceImpl implements AiChatModalService {
53 64  
54 65 @Override
55 66 public void add(AiChatModalAddReq req) {
  67 + // 校验 platform、type
  68 + validatePlatform(req.getPlatform());
  69 + validateModal(req.getPlatform(), req.getModal());
  70 + // 转换config
  71 + AiChatModalConfigVO aiChatModalConfigVO = convertConfig(req);
  72 + // 校验 modal config
  73 + validateModalConfig(aiChatModalConfigVO);
56 74 // 转换 do
57 75 AiChatModalDO insertChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
58   - //
  76 + // 设置默认属性
59 77 insertChatModalDO.setDisable(AiChatModalDisableEnum.NO.getValue());
  78 + insertChatModalDO.setConfig(JsonUtils.toJsonString(aiChatModalConfigVO));
60 79 // 保存数据库
61 80 aiChatModalMapper.insert(insertChatModalDO);
62 81 }
63 82  
64 83 @Override
65 84 public void update(Long id, AiChatModalAddReq req) {
  85 + // 校验 platform、type
  86 + validatePlatform(req.getPlatform());
  87 + validateModal(req.getPlatform(), req.getModal());
  88 + // 转换config
  89 + AiChatModalConfigVO aiChatModalConfigVO = convertConfig(req);
  90 + // 校验 modal config
  91 + validateModalConfig(aiChatModalConfigVO);
  92 +
66 93 // 校验模型是否存在
67 94 validateChatModalExists(id);
68 95 // 转换 updateChatModalDO
69 96 AiChatModalDO updateChatModalDO = AiChatModalConvert.INSTANCE.convertAiChatModalDO(req);
70 97 updateChatModalDO.setId(id);
  98 + updateChatModalDO.setConfig(JsonUtils.toJsonString(aiChatModalConfigVO));
71 99 // 更新数据库
72 100 aiChatModalMapper.updateById(updateChatModalDO);
73 101 }
... ... @@ -86,4 +114,52 @@ public class AiChatModalServiceImpl implements AiChatModalService {
86 114 throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
87 115 }
88 116 }
  117 +
  118 + private void validateModal(String platform, String modal) {
  119 + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(platform);
  120 + try {
  121 + if (AiPlatformEnum.QIAN_WEN == platformEnum) {
  122 + QianWenChatModal.valueOfModel(modal);
  123 + } else if (AiPlatformEnum.XING_HUO == platformEnum) {
  124 + XingHuoChatModel.valueOfModel(modal);
  125 + } else if (AiPlatformEnum.YI_YAN == platformEnum) {
  126 + YiYanChatModel.valueOfModel(modal);
  127 + } else {
  128 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_SUPPORTED_MODAL, platform);
  129 + }
  130 + } catch (IllegalArgumentException e) {
  131 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, e.getMessage());
  132 + }
  133 + }
  134 +
  135 + private void validatePlatform(String platform) {
  136 + try {
  137 + AiPlatformEnum.valueOfPlatform(platform);
  138 + } catch (IllegalArgumentException e) {
  139 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_PLATFORM_PARAMS_INCORRECT, e.getMessage());
  140 + }
  141 + }
  142 +
  143 + private void validateModalConfig(AiChatModalConfigVO aiChatModalConfigVO) {
  144 + Set<ConstraintViolation<AiChatModalConfigVO>> validate = ValidationUtil.validate(aiChatModalConfigVO);
  145 + for (ConstraintViolation<AiChatModalConfigVO> constraintViolation : validate) {
  146 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, constraintViolation.getMessage());
  147 + }
  148 + }
  149 +
  150 + private static AiChatModalConfigVO convertConfig(AiChatModalAddReq req) {
  151 + AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getPlatform());
  152 + AiChatModalConfigVO resVo = null;
  153 + if (AiPlatformEnum.CHAT_PLATFORM_LIST.contains(platformEnum)) {
  154 + resVo = JsonUtils.parseObject(JsonUtils.toJsonString(req.getConfig()), AiChatModalChatConfigVO.class);
  155 + } else if (AiPlatformEnum.OPEN_AI_DALL == platformEnum) {
  156 + resVo = JsonUtils.parseObject(JsonUtils.toJsonString(req.getConfig()), AiChatModalDallConfigVO.class);
  157 + }
  158 + if (resVo == null) {
  159 + throw new IllegalArgumentException("ai模型中config不能转换! json: " + req.getConfig());
  160 + }
  161 + resVo.setType(req.getModal());
  162 + resVo.setPlatform(req.getPlatform());
  163 + return resVo;
  164 + }
89 165 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java
... ... @@ -5,9 +5,9 @@ import cn.iocoder.yudao.framework.ai.image.ImageGeneration;
5 5 import cn.iocoder.yudao.framework.ai.image.ImagePrompt;
6 6 import cn.iocoder.yudao.framework.ai.image.ImageResponse;
7 7 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient;
8   -import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum;
  8 +import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageModelEnum;
9 9 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions;
10   -import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum;
  10 +import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
11 11 import cn.iocoder.yudao.framework.ai.midjourney.api.MidjourneyInteractionsApi;
12 12 import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MidjourneyWebSocketStarter;
13 13 import cn.iocoder.yudao.framework.ai.midjourney.webSocket.WssNotify;
... ... @@ -21,7 +21,6 @@ import cn.iocoder.yudao.module.ai.mapper.AiImageMapper;
21 21 import cn.iocoder.yudao.module.ai.service.AiImageService;
22 22 import cn.iocoder.yudao.module.ai.vo.AiImageDallDrawingReq;
23 23 import cn.iocoder.yudao.module.ai.vo.AiImageMidjourneyReq;
24   -import cn.iocoder.yudao.module.ai.vo.AiImageMidjourneyRes;
25 24 import jakarta.annotation.PostConstruct;
26 25 import lombok.AllArgsConstructor;
27 26 import lombok.extern.slf4j.Slf4j;
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalAddReq.java
... ... @@ -6,6 +6,8 @@ import jakarta.validation.constraints.Size;
6 6 import lombok.Data;
7 7 import lombok.experimental.Accessors;
8 8  
  9 +import java.util.Map;
  10 +
9 11 /**
10 12 * ai chat modal
11 13 *
... ... @@ -19,18 +21,24 @@ public class AiChatModalAddReq {
19 21  
20 22 @NotNull
21 23 @Schema(description = "模型名字")
22   - @Size(max = 60, message = "模型名字最大60")
23   - private String modelName;
  24 + @Size(max = 60, message = "模型名字最大60个字符")
  25 + private String name;
  26 +
  27 + @NotNull
  28 + @Size(max = 32, message = "模型平台最大32个字符")
  29 + @Schema(description = "模型平台 参考 AiPlatformEnum")
  30 + private String platform;
24 31  
25 32 @NotNull
26 33 @Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
27   - @Size(max = 32, message = "模型类型最大32")
28   - private String modelType;
  34 + @Size(max = 32, message = "模型类型最大32个字符")
  35 + private String modal;
29 36  
30 37 @Schema(description = "模型照片")
31   - private String modalImage;
  38 + @Size(max = 256, message = "模型照片地址最大256个字符")
  39 + private String imageUrl;
32 40  
33 41 @Schema(description = "模型配置JSON")
34   - private String modelConfig;
35   -
  42 +// @Size(max = 1024, message = "模型配置最大1024个字符")
  43 + private Map<String, Object> config;
36 44 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/vo/AiChatModalListRes.java
1 1 package cn.iocoder.yudao.module.ai.vo;
2 2  
  3 +import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
3 5 import lombok.Data;
4 6 import lombok.experimental.Accessors;
5 7  
... ... @@ -13,29 +15,25 @@ import lombok.experimental.Accessors;
13 15 @Data
14 16 @Accessors(chain = true)
15 17 public class AiChatModalListRes {
16   - /**
17   - * 编号
18   - */
  18 +
  19 + @Schema(description = "id")
19 20 private Long id;
20   - /**
21   - * 模型名字
22   - */
23   - private String modelName;
24   - /**
25   - * 模型类型(qianwen、yiyan、xinghuo、openai)
26   - */
27   - private String modelType;
28   - /**
29   - * 模型照片
30   - */
31   - private String modalImage;
32   - /**
33   - * 模型配置JSON
34   - */
35   - private String modelConfig;
36   - /**
37   - * 禁用 0、正常 1、禁用
38   - */
  21 +
  22 + @Schema(description = "模型平台 参考 AiPlatformEnum")
  23 + private String platform;
  24 +
  25 + @Schema(description = "模型类型 参考 YiYanChatModel、XingHuoChatModel")
  26 + private String modal;
  27 +
  28 + @Schema(description = "模型名字")
  29 + private String name;
  30 +
  31 + @Schema(description = "模型照片")
  32 + private String image;
  33 +
  34 + @Schema(description = "禁用 0、正常 1、禁用")
39 35 private Integer disable;
40 36  
  37 + @Schema(description = "modal 配置")
  38 + private String config;
41 39 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/resources/http/chat-modal.http
1 1  
2   -
3 2 ### chat call
4 3 GET {{baseUrl}}/ai/chat/modal/list
5 4 Authorization: {{token}}
6 5  
7 6  
8   -
9 7 ### chat call
10 8 PUT {{baseUrl}}/ai/chat/modal
11 9 Content-Type: application/json
12 10 Authorization: {{token}}
13 11  
14 12 {
15   - "modelName": "小红书Ai写作大模型",
16   - "modelType": "yiyan",
17   - "modalImage": "",
18   - "modelConfig": ""
  13 + "name": "小红书Ai写作大模型-plus",
  14 + "modal": "ERNIE-3.5-8K",
  15 + "platform": "yiyan",
  16 + "imageUrl": "",
  17 + "config": {
  18 + "topK": 0.6,
  19 + "topP": 0.6,
  20 + "temperature": 0.86,
  21 + "maxTokens": 2048
  22 + }
  23 +}
  24 +
  25 +### chat call
  26 +POST {{baseUrl}}/ai/chat/modal/7
  27 +Content-Type: application/json
  28 +Authorization: {{token}}
  29 +
  30 +{
  31 + "name": "小红书Ai写作大模型-plus",
  32 + "modal": "ERNIE-3.5-8K",
  33 + "platform": "yiyan",
  34 + "imageUrl": "",
  35 + "config": {
  36 + "topK": 0.6,
  37 + "topP": 0.6,
  38 + "temperature": 0.86,
  39 + "maxTokens": 2048
  40 + }
19 41 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java
1 1 package cn.iocoder.yudao.framework.ai;
2 2  
  3 +import com.google.common.collect.Lists;
3 4 import lombok.AllArgsConstructor;
4 5 import lombok.Getter;
5 6  
  7 +import java.util.List;
  8 +
6 9 /**
7 10 * ai 模型平台
8 11 *
... ... @@ -17,12 +20,27 @@ public enum AiPlatformEnum {
17 20 YI_YAN("yiyan", "一言"),
18 21 QIAN_WEN("qianwen", "千问"),
19 22 XING_HUO("xinghuo", "星火"),
  23 + OPEN_AI("openai", "openAi"),
  24 + OPEN_AI_DALL("dall", "dall"),
  25 + MIDJOURNEY("midjourney", "midjourney"),
20 26  
21 27 ;
22 28  
23 29 private String platform;
24 30 private String name;
25 31  
  32 + public static List<AiPlatformEnum> CHAT_PLATFORM_LIST = Lists.newArrayList(
  33 + AiPlatformEnum.YI_YAN,
  34 + AiPlatformEnum.QIAN_WEN,
  35 + AiPlatformEnum.XING_HUO,
  36 + AiPlatformEnum.OPEN_AI
  37 + );
  38 +
  39 + public static List<AiPlatformEnum> IMAGE_PLATFORM_LIST = Lists.newArrayList(
  40 + AiPlatformEnum.OPEN_AI_DALL,
  41 + AiPlatformEnum.MIDJOURNEY
  42 + );
  43 +
26 44 public static AiPlatformEnum valueOfPlatform(String platform) {
27 45 for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
28 46 if (itemEnum.getPlatform().equals(platform)) {
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
... ... @@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.ai.config;
3 3 import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
4 4 import cn.iocoder.yudao.framework.ai.chatxinghuo.XingHuoChatModel;
5 5 import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel;
6   -import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageModelEnum;
7   -import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageStyleEnum;
  6 +import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageModelEnum;
  7 +import cn.iocoder.yudao.framework.ai.imageopenai.enums.OpenAiImageStyleEnum;
8 8 import lombok.Data;
9 9 import lombok.experimental.Accessors;
10 10 import org.springframework.boot.context.properties.ConfigurationProperties;
... ...