diff --git a/yudao-module-ai/pom.xml b/yudao-module-ai/pom.xml index 4b02a7e00..95c836777 100644 --- a/yudao-module-ai/pom.xml +++ b/yudao-module-ai/pom.xml @@ -19,7 +19,8 @@ 国外:OpenAI、Ollama、Midjourney、StableDiffusion、Suno - 1.0.0-M6 + 1.0.0 + 1.0.0.2 1.0.2 @@ -75,65 +76,66 @@ org.springframework.ai - spring-ai-openai-spring-boot-starter + spring-ai-starter-model-openai ${spring-ai.version} org.springframework.ai - spring-ai-azure-openai-spring-boot-starter + spring-ai-starter-model-azure-openai ${spring-ai.version} org.springframework.ai - spring-ai-ollama-spring-boot-starter + spring-ai-starter-model-ollama ${spring-ai.version} org.springframework.ai - spring-ai-stability-ai-spring-boot-starter + spring-ai-starter-model-stability-ai ${spring-ai.version} com.alibaba.cloud.ai - spring-ai-alibaba-starter - ${spring-ai.version}.1 + spring-ai-alibaba-starter-dashscope + ${alibaba-ai.version} - org.springframework.ai - spring-ai-qianfan-spring-boot-starter - ${spring-ai.version} + org.springaicommunity + qianfan-spring-boot-starter + 1.0.0 org.springframework.ai - spring-ai-zhipuai-spring-boot-starter + spring-ai-starter-model-zhipuai ${spring-ai.version} org.springframework.ai - spring-ai-minimax-spring-boot-starter + spring-ai-starter-model-minimax ${spring-ai.version} - org.springframework.ai - spring-ai-moonshot-spring-boot-starter - ${spring-ai.version} + + org.springaicommunity + moonshot-spring-boot-starter + 1.0.0 org.springframework.ai - spring-ai-qdrant-store + spring-ai-starter-vector-store-qdrant ${spring-ai.version} org.springframework.ai - spring-ai-redis-store + spring-ai-starter-vector-store-redis ${spring-ai.version} @@ -144,7 +146,7 @@ org.springframework.ai - spring-ai-milvus-store + spring-ai-starter-vector-store-milvus ${spring-ai.version} diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java index a28d726b9..ae8a7e75f 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java @@ -14,10 +14,6 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlo import cn.iocoder.yudao.module.ai.framework.ai.core.model.suno.api.SunoApi; import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatModel; import lombok.extern.slf4j.Slf4j; -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusServiceClientProperties; -import org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreProperties; -import org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreProperties; -import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties; import org.springframework.ai.embedding.BatchingStrategy; import org.springframework.ai.embedding.TokenCountBatchingStrategy; import org.springframework.ai.model.tool.ToolCallingManager; @@ -26,6 +22,10 @@ import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator; import org.springframework.ai.tokenizer.TokenCountEstimator; +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusServiceClientProperties; +import org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreProperties; +import org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreProperties; +import org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/siliconflow/SiliconFlowImageModel.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/siliconflow/SiliconFlowImageModel.java index 43f8ad216..44a652309 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/siliconflow/SiliconFlowImageModel.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/siliconflow/SiliconFlowImageModel.java @@ -89,7 +89,7 @@ public class SiliconFlowImageModel implements ImageModel { var observationContext = ImageModelObservationContext.builder() .imagePrompt(imagePrompt) .provider(SiliconFlowApiConstants.PROVIDER_NAME) - .requestOptions(imagePrompt.getOptions()) + .imagePrompt(imagePrompt) .build(); return ImageModelObservationDocumentation.IMAGE_MODEL_OPERATION diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java index 671098a70..79214a032 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java @@ -9,9 +9,6 @@ import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.http.HttpUtil; -import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum; -import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; -import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowImageOptions; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.ai.controller.admin.image.vo.AiImageDrawReqVO; @@ -24,17 +21,20 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO; import cn.iocoder.yudao.module.ai.dal.mysql.image.AiImageMapper; import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum; +import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum; +import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; +import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowImageOptions; import cn.iocoder.yudao.module.ai.service.model.AiModelService; import cn.iocoder.yudao.module.infra.api.file.FileApi; import com.alibaba.cloud.ai.dashscope.image.DashScopeImageOptions; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springaicommunity.qianfan.QianFanImageOptions; import org.springframework.ai.image.ImageModel; import org.springframework.ai.image.ImageOptions; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; import org.springframework.ai.openai.OpenAiImageOptions; -import org.springframework.ai.qianfan.QianFanImageOptions; import org.springframework.ai.stabilityai.api.StabilityAiImageOptions; import org.springframework.ai.zhipuai.ZhiPuAiImageOptions; import org.springframework.scheduling.annotation.Async; @@ -140,10 +140,10 @@ public class AiImageServiceImpl implements AiImageService { private static ImageOptions buildImageOptions(AiImageDrawReqVO draw, AiModelDO model) { if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.OPENAI.getPlatform())) { // https://platform.openai.com/docs/api-reference/images/create - return OpenAiImageOptions.builder().withModel(model.getModel()) - .withHeight(draw.getHeight()).withWidth(draw.getWidth()) - .withStyle(MapUtil.getStr(draw.getOptions(), "style")) // 风格 - .withResponseFormat("b64_json") + return OpenAiImageOptions.builder().model(model.getModel()) + .height(draw.getHeight()).width(draw.getWidth()) + .style(MapUtil.getStr(draw.getOptions(), "style")) // 风格 + .responseFormat("b64_json") .build(); } else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.SILICON_FLOW.getPlatform())) { // https://docs.siliconflow.cn/cn/api-reference/images/images-generations diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java index ac3ff39a4..0744ff630 100644 --- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java +++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java @@ -2,18 +2,18 @@ package cn.iocoder.yudao.module.ai.util; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum; import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions; +import org.springaicommunity.moonshot.MoonshotChatOptions; +import org.springaicommunity.qianfan.QianFanChatOptions; import org.springframework.ai.azure.openai.AzureOpenAiChatOptions; import org.springframework.ai.chat.messages.*; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.minimax.MiniMaxChatOptions; -import org.springframework.ai.moonshot.MoonshotChatOptions; import org.springframework.ai.ollama.api.OllamaOptions; import org.springframework.ai.openai.OpenAiChatOptions; -import org.springframework.ai.qianfan.QianFanChatOptions; import org.springframework.ai.zhipuai.ZhiPuAiChatOptions; import java.util.Collections; @@ -43,18 +43,18 @@ public class AiUtils { switch (platform) { case TONG_YI: return DashScopeChatOptions.builder().withModel(model).withTemperature(temperature).withMaxToken(maxTokens) - .withFunctions(toolNames).withToolContext(toolContext).build(); + .withToolNames(toolNames).withToolContext(toolContext).build(); case YI_YAN: return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build(); case ZHI_PU: return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) - .functions(toolNames).toolContext(toolContext).build(); + .toolNames(toolNames).toolContext(toolContext).build(); case MINI_MAX: return MiniMaxChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) - .functions(toolNames).toolContext(toolContext).build(); + .toolNames(toolNames).toolContext(toolContext).build(); case MOONSHOT: return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) - .functions(toolNames).toolContext(toolContext).build(); + .toolNames(toolNames).toolContext(toolContext).build(); case OPENAI: case DEEP_SEEK: // 复用 OpenAI 客户端 case DOU_BAO: // 复用 OpenAI 客户端 diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OpenAIChatModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OpenAIChatModelTests.java index ff866fe40..c650fd042 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OpenAIChatModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/OpenAIChatModelTests.java @@ -25,10 +25,10 @@ public class OpenAIChatModelTests { private final OpenAiChatModel chatModel = OpenAiChatModel.builder() .openAiApi(OpenAiApi.builder() .baseUrl("https://api.holdai.top") - .apiKey("sk-aN6nWn3fILjrgLFT0fC4Aa60B72e4253826c77B29dC94f17") // apiKey + .apiKey("sk-PytRecQlmjEteoa2RRN6cGnwslo72UUPLQVNEMS6K9yjbmpD") // apiKey .build()) .defaultOptions(OpenAiChatOptions.builder() - .model(OpenAiApi.ChatModel.GPT_4_O) // 模型 + .model(OpenAiApi.ChatModel.GPT_4_1_NANO) // 模型 .temperature(0.7) .build()) .build(); diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java index 4f0efdb20..4f2e27edd 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java @@ -22,14 +22,17 @@ import java.util.List; */ public class TongYiChatModelTests { - private final DashScopeChatModel chatModel = new DashScopeChatModel( - new DashScopeApi("sk-7d903764249848cfa912733146da12d1"), - DashScopeChatOptions.builder() + private final DashScopeChatModel chatModel = DashScopeChatModel.builder() + .dashScopeApi(DashScopeApi.builder() + .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0") + .build()) + .defaultOptions( DashScopeChatOptions.builder() .withModel("qwen1.5-72b-chat") // 模型 // .withModel("deepseek-r1") // 模型(deepseek-r1) // .withModel("deepseek-v3") // 模型(deepseek-v3) // .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b) - .build()); + .build()) + .build(); @Test @Disabled diff --git a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/OpenAiImageModelTests.java b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/OpenAiImageModelTests.java index 49015b9b9..1b124529d 100644 --- a/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/OpenAiImageModelTests.java +++ b/yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/OpenAiImageModelTests.java @@ -18,7 +18,7 @@ public class OpenAiImageModelTests { private final OpenAiImageModel imageModel = new OpenAiImageModel(OpenAiImageApi.builder() .baseUrl("https://api.holdai.top") // apiKey - .apiKey("sk-aN6nWn3fILjrgLFT0fC4Aa60B72e4253826c77B29dC94f17") + .apiKey("sk-PytRecQlmjEteoa2RRN6cGnwslo72UUPLQVNEMS6K9yjbmpD") .build()); @Test @@ -26,8 +26,8 @@ public class OpenAiImageModelTests { public void testCall() { // 准备参数 ImageOptions options = OpenAiImageOptions.builder() - .withModel(OpenAiImageApi.ImageModel.DALL_E_2.getValue()) // 这个模型比较便宜 - .withHeight(256).withWidth(256) + .model(OpenAiImageApi.ImageModel.DALL_E_2.getValue()) // 这个模型比较便宜 + .height(256).width(256) .build(); ImagePrompt prompt = new ImagePrompt("中国长城!", options); diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml index db07245c6..344e97ecf 100644 --- a/yudao-server/src/main/resources/application-dev.yaml +++ b/yudao-server/src/main/resources/application-dev.yaml @@ -6,8 +6,8 @@ server: spring: autoconfigure: exclude: - - org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建 - - org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建 + - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建 + - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建 # 数据源配置项 datasource: druid: # Druid 【监控】相关的全局配置 diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 2849775e6..5d23b9b70 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -10,8 +10,8 @@ spring: - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置 - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置 - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置 - - org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建 - - org.springframework.ai.autoconfigure.vectorstore.milvus.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建 + - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 禁用 AI 模块的 Qdrant,手动创建 + - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 禁用 AI 模块的 Milvus,手动创建 # 数据源配置项 datasource: druid: # Druid 【监控】相关的全局配置