Commit abc51c670ae3640462a0d2fe26b6543faf657cde
Merge remote-tracking branch 'origin/master-jdk21-ai' into master-jdk21-ai
Showing
10 changed files
with
82 additions
and
59 deletions
script/idea/http-client.env.json
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/AiChatRoleEnum.java
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
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 | -} |