Commit d14c13b2fc4870fc244b22a2033d152fc0983c45

Authored by cherishsince
1 parent 198dae62

【增加】midjourney 自动配置。

yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
1 package cn.iocoder.yudao.framework.ai.config; 1 package cn.iocoder.yudao.framework.ai.config;
2 2
  3 +import cn.hutool.core.io.IoUtil;
3 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient; 4 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatClient;
4 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal; 5 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenChatModal;
5 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions; 6 import cn.iocoder.yudao.framework.ai.chatqianwen.QianWenOptions;
@@ -13,10 +14,21 @@ import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanApi; @@ -13,10 +14,21 @@ import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanApi;
13 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageApi; 14 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageApi;
14 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient; 15 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageClient;
15 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions; 16 import cn.iocoder.yudao.framework.ai.imageopenai.OpenAiImageOptions;
  17 +import cn.iocoder.yudao.framework.ai.midjourney.MidjourneyConfig;
  18 +import cn.iocoder.yudao.framework.ai.midjourney.api.MidjourneyInteractionsApi;
  19 +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.MidjourneyWebSocketStarter;
  20 +import cn.iocoder.yudao.framework.ai.midjourney.webSocket.listener.MidjourneyMessageListener;
  21 +import org.jetbrains.annotations.NotNull;
16 import org.springframework.boot.autoconfigure.AutoConfiguration; 22 import org.springframework.boot.autoconfigure.AutoConfiguration;
17 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
18 import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 import org.springframework.boot.context.properties.EnableConfigurationProperties;
  25 +import org.springframework.context.ApplicationContext;
19 import org.springframework.context.annotation.Bean; 26 import org.springframework.context.annotation.Bean;
  27 +import org.springframework.core.io.Resource;
  28 +
  29 +import java.io.IOException;
  30 +import java.util.HashMap;
  31 +import java.util.Map;
20 32
21 /** 33 /**
22 * ai 自动配置 34 * ai 自动配置
@@ -103,4 +115,45 @@ public class YudaoAiAutoConfiguration { @@ -103,4 +115,45 @@ public class YudaoAiAutoConfiguration {
103 .setStyle(openAiImageProperties.getStyle()) 115 .setStyle(openAiImageProperties.getStyle())
104 ); 116 );
105 } 117 }
  118 +
  119 + @Bean
  120 + @ConditionalOnProperty(value = "yudao.ai.midjourney.enable", havingValue = "true")
  121 + public MidjourneyWebSocketStarter midjourneyWebSocketStarter(ApplicationContext applicationContext, YudaoAiProperties yudaoAiProperties) {
  122 + // 获取 midjourneyProperties
  123 + YudaoAiProperties.MidjourneyProperties midjourneyProperties = yudaoAiProperties.getMidjourney();
  124 + // 获取 midjourneyConfig
  125 + MidjourneyConfig midjourneyConfig = getMidjourneyConfig(applicationContext, midjourneyProperties);
  126 + // 创建 socket messageListener
  127 + MidjourneyMessageListener messageListener = new MidjourneyMessageListener(midjourneyConfig);
  128 + // 创建 MidjourneyWebSocketStarter
  129 + return new MidjourneyWebSocketStarter(midjourneyProperties.getWssUrl(), null, midjourneyConfig, messageListener);
  130 + }
  131 +
  132 + @Bean
  133 + @ConditionalOnProperty(value = "yudao.ai.midjourney.enable", havingValue = "true")
  134 + public MidjourneyInteractionsApi midjourneyInteractionsApi(ApplicationContext applicationContext, YudaoAiProperties yudaoAiProperties) {
  135 + // 获取 midjourneyConfig
  136 + MidjourneyConfig midjourneyConfig = getMidjourneyConfig(applicationContext, yudaoAiProperties.getMidjourney());
  137 + // 创建 MidjourneyInteractionsApi
  138 + return new MidjourneyInteractionsApi(midjourneyConfig);
  139 + }
  140 +
  141 +
  142 + private static @NotNull MidjourneyConfig getMidjourneyConfig(ApplicationContext applicationContext,
  143 + YudaoAiProperties.MidjourneyProperties midjourneyProperties) {
  144 + Map<String, String> requestTemplates = new HashMap<>();
  145 + try {
  146 + Resource[] resources = applicationContext.getResources("classpath:http-body/*.json");
  147 + for (var resource : resources) {
  148 + String filename = resource.getFilename();
  149 + String params = IoUtil.readUtf8(resource.getInputStream());
  150 + requestTemplates.put(filename.substring(0, filename.length() - 5), params);
  151 + }
  152 + } catch (IOException e) {
  153 + throw new IllegalArgumentException("Midjourney json模板初始化出错! " + e.getMessage());
  154 + }
  155 + // 创建 midjourneyConfig
  156 + return new MidjourneyConfig(midjourneyProperties.getToken(),
  157 + midjourneyProperties.getGuildId(), midjourneyProperties.getChannelId(), requestTemplates);
  158 + }
106 } 159 }
107 \ No newline at end of file 160 \ No newline at end of file
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
@@ -26,6 +26,7 @@ public class YudaoAiProperties { @@ -26,6 +26,7 @@ public class YudaoAiProperties {
26 private XingHuoProperties xinghuo; 26 private XingHuoProperties xinghuo;
27 private YiYanProperties yiyan; 27 private YiYanProperties yiyan;
28 private OpenAiImageProperties openAiImage; 28 private OpenAiImageProperties openAiImage;
  29 + private MidjourneyProperties midjourney;
29 30
30 @Data 31 @Data
31 @Accessors(chain = true) 32 @Accessors(chain = true)
@@ -94,6 +95,8 @@ public class YudaoAiProperties { @@ -94,6 +95,8 @@ public class YudaoAiProperties {
94 @Data 95 @Data
95 @Accessors(chain = true) 96 @Accessors(chain = true)
96 public static class OpenAiImageProperties { 97 public static class OpenAiImageProperties {
  98 + private boolean enable = false;
  99 +
97 /** 100 /**
98 * api key 101 * api key
99 */ 102 */
@@ -107,4 +110,27 @@ public class YudaoAiProperties { @@ -107,4 +110,27 @@ public class YudaoAiProperties {
107 */ 110 */
108 private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID; 111 private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID;
109 } 112 }
  113 +
  114 + @Data
  115 + @Accessors(chain = true)
  116 + public static class MidjourneyProperties {
  117 + private boolean enable = false;
  118 +
  119 + /**
  120 + * socket 链接地址
  121 + */
  122 + private String wssUrl = "wss://gateway.discord.gg";
  123 + /**
  124 + * token
  125 + */
  126 + private String token;
  127 + /**
  128 + * 服务id
  129 + */
  130 + private String guildId;
  131 + /**
  132 + * 频道id
  133 + */
  134 + private String channelId;
  135 + }
110 } 136 }
yudao-server/src/main/resources/application-local.yaml
@@ -260,7 +260,11 @@ yudao: @@ -260,7 +260,11 @@ yudao:
260 api-key: ${OPEN_AI_KEY} 260 api-key: ${OPEN_AI_KEY}
261 model: dall_e_2 261 model: dall_e_2
262 style: vivid 262 style: vivid
263 - 263 + midjourney:
  264 + enable: true
  265 + token: OTcyNzIxMzA0ODkxNDUzNDUw.G_vMOz.BO_Q0sXAD80u5ZKIHPNYDTRX_FgeKL3cKFc53I
  266 + guild-id: 1225608134878302329
  267 + channel-id: 1225608134878302332
264 captcha: 268 captcha:
265 enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试; 269 enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
266 security: 270 security: