Commit abc51c670ae3640462a0d2fe26b6543faf657cde

Authored by cherishsince
2 parents 18aeb072 c6c00370

Merge remote-tracking branch 'origin/master-jdk21-ai' into master-jdk21-ai

script/idea/http-client.env.json
1 1 {
2 2 "local": {
3 3 "baseUrl": "http://127.0.0.1:48080/admin-api",
4   - "token": "Bearer 1c2ce60de96a4fb0bf5bea9604099a3d",
  4 + "token": "test1",
5 5 "adminTenentId": "1",
6 6  
7 7 "appApi": "http://127.0.0.1:48080/app-api",
... ...
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java
... ... @@ -39,6 +39,7 @@ public enum AiChatRoleEnum implements IntArrayValuable {
39 39 除此之外不要任何解释性语句。
40 40 """);
41 41  
  42 + // TODO @xin:这个 role 是不是删除掉好点哈。= = 目前主要是没做角色枚举。这里多了 role 反倒容易误解哈
42 43 /**
43 44 * 角色
44 45 */
... ...
yudao-module-ai/yudao-module-ai-biz/pom.xml
... ... @@ -60,9 +60,5 @@
60 60 <groupId>cn.iocoder.boot</groupId>
61 61 <artifactId>yudao-spring-boot-starter-test</artifactId>
62 62 </dependency>
63   - <dependency>
64   - <groupId>cn.iocoder.boot</groupId>
65   - <artifactId>yudao-spring-boot-starter-excel</artifactId>
66   - </dependency>
67 63 </dependencies>
68 64 </project>
69 65 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/mindmap/AiMindMapMapper.java
... ... @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.mindmap.AiMindMapDO;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
7 7 /**
8   - * AI 音乐 Mapper
  8 + * AI 思维导图 Mapper
9 9 *
10 10 * @author xiaoxin
11 11 */
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
... ... @@ -18,12 +18,15 @@ import com.alibaba.cloud.ai.tongyi.TongYiConnectionProperties;
18 18 import com.alibaba.cloud.ai.tongyi.chat.TongYiChatModel;
19 19 import com.alibaba.cloud.ai.tongyi.chat.TongYiChatProperties;
20 20 import com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel;
  21 +import com.alibaba.cloud.ai.tongyi.image.TongYiImagesProperties;
21 22 import com.alibaba.dashscope.aigc.generation.Generation;
  23 +import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
22 24 import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration;
23 25 import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
24 26 import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration;
25 27 import org.springframework.ai.autoconfigure.qianfan.QianFanChatProperties;
26 28 import org.springframework.ai.autoconfigure.qianfan.QianFanConnectionProperties;
  29 +import org.springframework.ai.autoconfigure.qianfan.QianFanImageProperties;
27 30 import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration;
28 31 import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiChatProperties;
29 32 import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties;
... ... @@ -111,6 +114,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
111 114 public ImageModel getDefaultImageModel(AiPlatformEnum platform) {
112 115 //noinspection EnhancedSwitchMigration
113 116 switch (platform) {
  117 + case TONG_YI:
  118 + return SpringUtil.getBean(TongYiImagesModel.class);
  119 + case YI_YAN:
  120 + return SpringUtil.getBean(QianFanImageModel.class);
114 121 case OPENAI:
115 122 return SpringUtil.getBean(OpenAiImageModel.class);
116 123 case STABLE_DIFFUSION:
... ... @@ -124,14 +131,14 @@ public class AiModelFactoryImpl implements AiModelFactory {
124 131 public ImageModel getOrCreateImageModel(AiPlatformEnum platform, String apiKey, String url) {
125 132 //noinspection EnhancedSwitchMigration
126 133 switch (platform) {
  134 + case TONG_YI:
  135 + return buildTongYiImagesModel(apiKey);
  136 + case YI_YAN:
  137 + return buildQianFanImageModel(apiKey);
127 138 case OPENAI:
128 139 return buildOpenAiImageModel(apiKey, url);
129 140 case STABLE_DIFFUSION:
130 141 return buildStabilityAiImageModel(apiKey, url);
131   - case TONG_YI:
132   - return SpringUtil.getBean(TongYiImagesModel.class);
133   - case YI_YAN:
134   - return buildQianFanImageModel(apiKey);
135 142 default:
136 143 throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
137 144 }
... ... @@ -175,6 +182,14 @@ public class AiModelFactoryImpl implements AiModelFactory {
175 182 return new TongYiAutoConfiguration().tongYiChatClient(generation, chatOptions, connectionProperties);
176 183 }
177 184  
  185 + private static TongYiImagesModel buildTongYiImagesModel(String key) {
  186 + ImageSynthesis imageSynthesis = SpringUtil.getBean(ImageSynthesis.class);
  187 + TongYiImagesProperties imagesOptions = SpringUtil.getBean(TongYiImagesProperties.class);
  188 + TongYiConnectionProperties connectionProperties = new TongYiConnectionProperties();
  189 + connectionProperties.setApiKey(key);
  190 + return new TongYiAutoConfiguration().tongYiImagesClient(imageSynthesis, imagesOptions, connectionProperties);
  191 + }
  192 +
178 193 /**
179 194 * 可参考 {@link QianFanAutoConfiguration#qianFanChatModel(QianFanConnectionProperties, QianFanChatProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)}
180 195 */
... ... @@ -188,6 +203,18 @@ public class AiModelFactoryImpl implements AiModelFactory {
188 203 }
189 204  
190 205 /**
  206 + * 可参考 {@link QianFanAutoConfiguration#qianFanImageModel(QianFanConnectionProperties, QianFanImageProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)}
  207 + */
  208 + private QianFanImageModel buildQianFanImageModel(String key) {
  209 + List<String> keys = StrUtil.split(key, '|');
  210 + Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式");
  211 + String appKey = keys.get(0);
  212 + String secretKey = keys.get(1);
  213 + QianFanImageApi qianFanApi = new QianFanImageApi(appKey, secretKey);
  214 + return new QianFanImageModel(qianFanApi);
  215 + }
  216 +
  217 + /**
191 218 * 可参考 {@link YudaoAiAutoConfiguration#deepSeekChatModel(YudaoAiProperties)}
192 219 */
193 220 private static DeepSeekChatModel buildDeepSeekChatModel(String apiKey) {
... ... @@ -246,8 +273,4 @@ public class AiModelFactoryImpl implements AiModelFactory {
246 273 return new StabilityAiImageModel(stabilityAiApi);
247 274 }
248 275  
249   - private QianFanImageModel buildQianFanImageModel(String key) {
250   - List<String> keys = StrUtil.split(key, '|');
251   - return new QianFanImageModel(new QianFanImageApi(keys.get(0), keys.get(1)));
252   - }
253 276 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageModelTests.java
... ... @@ -21,7 +21,7 @@ public class OpenAiImageModelTests {
21 21 "https://api.holdai.top",
22 22 "sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf",
23 23 RestClient.builder());
24   - private final OpenAiImageModel imageClient = new OpenAiImageModel(imageApi);
  24 + private final OpenAiImageModel imageModel = new OpenAiImageModel(imageApi);
25 25  
26 26 @Test
27 27 @Disabled
... ... @@ -34,7 +34,7 @@ public class OpenAiImageModelTests {
34 34 ImagePrompt prompt = new ImagePrompt("中国长城!", options);
35 35  
36 36 // 方法调用
37   - ImageResponse response = imageClient.call(prompt);
  37 + ImageResponse response = imageModel.call(prompt);
38 38 // 打印结果
39 39 System.out.println(response);
40 40 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/QianFanImageTests.java
... ... @@ -7,7 +7,6 @@ import org.springframework.ai.image.ImagePrompt;
7 7 import org.springframework.ai.image.ImageResponse;
8 8 import org.springframework.ai.qianfan.QianFanImageModel;
9 9 import org.springframework.ai.qianfan.QianFanImageOptions;
10   -import org.springframework.ai.qianfan.api.QianFanApi;
11 10 import org.springframework.ai.qianfan.api.QianFanImageApi;
12 11  
13 12 /**
... ... @@ -19,7 +18,7 @@ public class QianFanImageTests {
19 18 public void callTest() {
20 19 // todo @芋艿 千帆sdk有个错误,暂时没找到问题
21 20 QianFanImageApi qianFanImageApi = new QianFanImageApi(
22   - "ghbbvbW2t7HK7WtYmEITAupm", "njJEr5AsQ5fkB3ucYYDjiQqsOZK20SGb");
  21 + "qS8k8dYr2nXunagK4SSU8Xjj", "pHGbx51ql2f0hOyabQvSZezahVC3hh3e");
23 22 QianFanImageModel qianFanImageModel = new QianFanImageModel(qianFanImageApi);
24 23  
25 24 QianFanImageOptions imageOptions = QianFanImageOptions.builder()
... ... @@ -45,4 +44,6 @@ public class QianFanImageTests {
45 44 ImageResponse imageResponse = imageModel.call(imagePrompt);
46 45 }
47 46  
  47 +
  48 +
48 49 }
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/StabilityAiImageModelTests.java
... ... @@ -24,7 +24,7 @@ public class StabilityAiImageModelTests {
24 24  
25 25 private final StabilityAiApi imageApi = new StabilityAiApi(
26 26 "sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx");
27   - private final StabilityAiImageModel imageClient = new StabilityAiImageModel(imageApi);
  27 + private final StabilityAiImageModel imageModel = new StabilityAiImageModel(imageApi);
28 28  
29 29 @Test
30 30 @Disabled
... ... @@ -37,7 +37,7 @@ public class StabilityAiImageModelTests {
37 37 ImagePrompt prompt = new ImagePrompt("great wall", options);
38 38  
39 39 // 方法调用
40   - ImageResponse response = imageClient.call(prompt);
  40 + ImageResponse response = imageModel.call(prompt);
41 41 // 打印结果
42 42 String b64Json = response.getResult().getOutput().getB64Json();
43 43 System.out.println(response);
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/TongYiImagesModelTest.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.image;
  2 +
  3 +import com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel;
  4 +import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
  5 +import com.alibaba.dashscope.utils.Constants;
  6 +import org.junit.jupiter.api.Test;
  7 +import org.springframework.ai.image.ImageOptions;
  8 +import org.springframework.ai.image.ImagePrompt;
  9 +import org.springframework.ai.image.ImageResponse;
  10 +import org.springframework.ai.openai.OpenAiImageOptions;
  11 +
  12 +/**
  13 + * {@link com.alibaba.cloud.ai.tongyi.image.TongYiImagesModel} 集成测试类
  14 + *
  15 + * @author fansili
  16 + */
  17 +public class TongYiImagesModelTest {
  18 +
  19 + private final ImageSynthesis imageApi = new ImageSynthesis();
  20 + private final TongYiImagesModel imageModel = new TongYiImagesModel(imageApi);
  21 +
  22 + static {
  23 + Constants.apiKey = "sk-Zsd81gZYg7";
  24 + }
  25 +
  26 + @Test
  27 + public void imageCallTest() {
  28 + // 准备参数
  29 + ImageOptions options = OpenAiImageOptions.builder()
  30 + .withModel(ImageSynthesis.Models.WANX_V1)
  31 + .withHeight(256).withWidth(256)
  32 + .build();
  33 + ImagePrompt prompt = new ImagePrompt("中国长城!", options);
  34 +
  35 + // 方法调用
  36 + ImageResponse response = imageModel.call(prompt);
  37 + // 打印结果
  38 + System.out.println(response);
  39 + }
  40 +
  41 +}
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/TongYiImagesModelTests.java deleted
1   -package cn.iocoder.yudao.framework.ai.image;
2   -
3   -import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
4   -import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
5   -import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
6   -import com.alibaba.dashscope.exception.NoApiKeyException;
7   -import com.alibaba.dashscope.utils.Constants;
8   -import com.alibaba.fastjson.JSON;
9   -import org.junit.jupiter.api.Test;
10   -
11   -import java.util.Map;
12   -
13   -// TODO @fan:改成 TongYiImagesModel 哈
14   -/**
15   - * 通义万象
16   - */
17   -public class TongYiImagesModelTests {
18   -
19   - @Test
20   - public void imageCallTest() throws NoApiKeyException {
21   - // 设置 api key
22   - Constants.apiKey = "sk-Zsd81gZYg7";
23   - ImageSynthesisParam param =
24   - ImageSynthesisParam.builder()
25   - .model(ImageSynthesis.Models.WANX_V1)
26   - .n(4)
27   - .size("1024*1024")
28   - .prompt("雄鹰自由自在的在蓝天白云下飞翔")
29   - .build();
30   - // 创建 ImageSynthesis
31   - ImageSynthesis is = new ImageSynthesis();
32   - // 调用 call 生成 image
33   - ImageSynthesisResult call = is.call(param);
34   - System.err.println(JSON.toJSON(call));
35   - for (Map<String, String> result : call.getOutput().getResults()) {
36   - System.err.println("地址: " + result.get("url"));
37   - }
38   - }
39   -}