diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendRespVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendRespVO.java index 9ea7900cb..58ba05659 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendRespVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/vo/message/AiChatMessageSendRespVO.java @@ -28,7 +28,7 @@ public class AiChatMessageSendRespVO { @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊") private String content; - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-05-12 12:51") + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalDallConfigVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalDallConfigVO.java index d77b4ec87..c828c9cf5 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalDallConfigVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/vo/AiChatModalDallConfigVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.ai.dal.vo; -import org.springframework.ai.models.openai.enums.OpenAiImageStyleEnum; +import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageStyleEnum; import lombok.Data; import lombok.experimental.Accessors; diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java index 4727127c9..20768c21e 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java @@ -6,10 +6,8 @@ import cn.iocoder.yudao.framework.ai.core.exception.AiException; import org.springframework.ai.image.ImageGeneration; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; -import org.springframework.ai.models.openai.OpenAiImageClient; -import org.springframework.ai.models.openai.OpenAiImageOptions; -import org.springframework.ai.models.openai.enums.OpenAiImageModelEnum; -import org.springframework.ai.models.openai.enums.OpenAiImageStyleEnum; +import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageModelEnum; +import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageStyleEnum; import org.springframework.ai.models.midjourney.api.MidjourneyInteractionsApi; import org.springframework.ai.models.midjourney.api.req.ReRollReq; import org.springframework.ai.models.midjourney.webSocket.MidjourneyWebSocketStarter; @@ -29,6 +27,8 @@ import cn.iocoder.yudao.module.ai.service.AiImageService; import jakarta.annotation.PostConstruct; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.ai.openai.OpenAiImageClient; +import org.springframework.ai.openai.OpenAiImageOptions; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -95,8 +95,8 @@ public class AiImageServiceImpl implements AiImageService { try { // 转换openai 参数 OpenAiImageOptions openAiImageOptions = new OpenAiImageOptions(); - openAiImageOptions.setModel(openAiImageModelEnum); - openAiImageOptions.setStyle(openAiImageStyleEnum); + openAiImageOptions.setModel(openAiImageModelEnum.getModel()); + openAiImageOptions.setStyle(openAiImageStyleEnum.getStyle()); openAiImageOptions.setSize(req.getSize()); ImageResponse imageResponse = openAiImageClient.call(new ImagePrompt(req.getPrompt(), openAiImageOptions)); // 发送 diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/midjourneyHandler/YuDaoMidjourneyMessageHandler.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/midjourneyHandler/YuDaoMidjourneyMessageHandler.java index d1ccc080e..c3c9d44d0 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/midjourneyHandler/YuDaoMidjourneyMessageHandler.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/midjourneyHandler/YuDaoMidjourneyMessageHandler.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.service.midjourneyHandler; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import org.springframework.ai.models.midjourney.MidjourneyMessage; import org.springframework.ai.models.midjourney.constants.MidjourneyGennerateStatusEnum; import org.springframework.ai.models.midjourney.webSocket.MidjourneyMessageHandler; @@ -11,7 +12,6 @@ import cn.iocoder.yudao.module.ai.convert.AiImageConvert; import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO; import cn.iocoder.yudao.module.ai.dal.mysql.AiImageMapper; import cn.iocoder.yudao.module.ai.enums.AiImageDrawingStatusEnum; -import com.alibaba.fastjson2.JSON; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml b/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml index 2195b4bcc..2188ad908 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml @@ -12,139 +12,48 @@ yudao-spring-boot-starter-ai - - 21 - 21 - UTF-8 - - - org.springframework - spring-core + io.springboot.ai + spring-ai-core + 1.0.3 - com.fasterxml.jackson.core - jackson-databind + io.springboot.ai + spring-ai-openai + 1.0.3 + - org.springframework - spring-context - - - net.jodah - typetools - 0.6.3 - compile - - - com.github.victools - jsonschema-module-jackson - 4.31.1 - compile - - - com.github.victools - jsonschema-module-swagger-2 - 4.33.1 - - - com.github.victools - jsonschema-generator - 4.31.1 - compile - - - io.projectreactor - reactor-core - - - org.springframework.cloud - spring-cloud-function-context - 4.1.0 - compile - - - org.antlr - stringtemplate - 4.0.2 - compile - - - org.projectlombok - lombok - - - org.springframework - spring-web - - - org.springframework - spring-webflux - - - org.springframework.retry - spring-retry - - - junit - junit - test - - - cn.hutool - hutool-all - test - - - com.squareup.okhttp3 - okhttp - 4.12.0 - test - - - io.projectreactor.netty - reactor-netty - - - cn.hutool - hutool-all + cn.iocoder.boot + yudao-common + com.alibaba dashscope-sdk-java 2.11.0 + - org.apache.httpcomponents - httpclient - 4.5.14 - compile + junit + junit + test + + + org.springframework.boot spring-boot-starter-websocket - - - com.fasterxml.jackson.core - jackson-databind - - - com.alibaba.fastjson2 - fastjson2 - 2.0.45 - + com.squareup.okhttp3 okhttp - - com.google.guava - guava - net.dv8tion JDA @@ -156,10 +65,6 @@ - - cn.iocoder.boot - yudao-common - \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java index 88581f88a..b37938d4a 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java @@ -11,9 +11,6 @@ import org.springframework.ai.models.xinghuo.api.XingHuoApi; import org.springframework.ai.models.yiyan.YiYanChatClient; import org.springframework.ai.models.yiyan.YiYanOptions; import org.springframework.ai.models.yiyan.api.YiYanApi; -import org.springframework.ai.models.openai.OpenAiImageApi; -import org.springframework.ai.models.openai.OpenAiImageClient; -import org.springframework.ai.models.openai.OpenAiImageOptions; import org.springframework.ai.models.midjourney.MidjourneyConfig; import org.springframework.ai.models.midjourney.MidjourneyMessage; import org.springframework.ai.models.midjourney.api.MidjourneyInteractionsApi; @@ -22,6 +19,10 @@ import org.springframework.ai.models.midjourney.webSocket.MidjourneyWebSocketSta import org.springframework.ai.models.midjourney.webSocket.listener.MidjourneyMessageListener; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; +import org.springframework.ai.openai.OpenAiImageClient; +import org.springframework.ai.openai.OpenAiImageOptions; +import org.springframework.ai.openai.api.OpenAiImageApi; +import org.springframework.ai.retry.RetryUtils; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -72,10 +73,10 @@ public class YudaoAiAutoConfiguration { YudaoAiProperties.QianWenProperties qianWenProperties = yudaoAiProperties.getQianwen(); // 转换配置 QianWenOptions qianWenOptions = new QianWenOptions(); - qianWenOptions.setTopK(qianWenProperties.getTopK()); +// qianWenOptions.setTopK(qianWenProperties.getTopK()); TODO 芋艿:后续弄 qianWenOptions.setTopP(qianWenProperties.getTopP()); qianWenOptions.setMaxTokens(qianWenProperties.getMaxTokens()); - qianWenOptions.setTemperature(qianWenProperties.getTemperature()); +// qianWenOptions.setTemperature(qianWenProperties.getTemperature()); TODO 芋艿:后续弄 return new QianWenChatClient( new QianWenApi( qianWenProperties.getApiKey(), @@ -91,7 +92,7 @@ public class YudaoAiAutoConfiguration { YudaoAiProperties.YiYanProperties yiYanProperties = yudaoAiProperties.getYiyan(); // 转换配置 YiYanOptions yiYanOptions = new YiYanOptions(); - yiYanOptions.setTopK(yiYanProperties.getTopK()); +// yiYanOptions.setTopK(yiYanProperties.getTopK()); TODO 芋艿:后续弄 yiYanOptions.setTopP(yiYanProperties.getTopP()); yiYanOptions.setTemperature(yiYanProperties.getTemperature()); yiYanOptions.setMaxOutputTokens(yiYanProperties.getMaxTokens()); @@ -106,19 +107,19 @@ public class YudaoAiAutoConfiguration { ); } - @Bean @ConditionalOnProperty(value = "yudao.ai.openAiImage.enable", havingValue = "true") public OpenAiImageClient openAiImageClient(YudaoAiProperties yudaoAiProperties) { YudaoAiProperties.OpenAiImageProperties openAiImageProperties = yudaoAiProperties.getOpenAiImage(); + OpenAiImageOptions openAiImageOptions = new OpenAiImageOptions(); + openAiImageOptions.setModel(openAiImageProperties.getModel().getModel()); + openAiImageOptions.setStyle(openAiImageProperties.getStyle().getStyle()); + openAiImageOptions.setResponseFormat("url"); // TODO 芋艿:OpenAiImageOptions.ResponseFormatEnum.URL.getValue() // 创建 client return new OpenAiImageClient( new OpenAiImageApi(openAiImageProperties.getApiKey()), - new OpenAiImageOptions() - .setModel(openAiImageProperties.getModel()) - .setResponseFormat(OpenAiImageOptions.ResponseFormatEnum.URL.getValue()) - .setStyle(openAiImageProperties.getStyle()) - ); + openAiImageOptions, + RetryUtils.DEFAULT_RETRY_TEMPLATE); } @Bean @@ -157,7 +158,6 @@ public class YudaoAiAutoConfiguration { return new MidjourneyInteractionsApi(midjourneyConfig); } - private static @NotNull MidjourneyConfig getMidjourneyConfig(ApplicationContext applicationContext, YudaoAiProperties.MidjourneyProperties midjourneyProperties) { Map requestTemplates = new HashMap<>(); diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java index a23b9109c..a228a0045 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java +++ b/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; import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; import org.springframework.ai.models.xinghuo.XingHuoChatModel; import org.springframework.ai.models.yiyan.YiYanChatModel; -import org.springframework.ai.models.openai.enums.OpenAiImageModelEnum; -import org.springframework.ai.models.openai.enums.OpenAiImageStyleEnum; +import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageModelEnum; +import cn.iocoder.yudao.framework.ai.core.enums.OpenAiImageStyleEnum; import lombok.Data; import lombok.experimental.Accessors; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -95,6 +95,7 @@ public class YudaoAiProperties { @Data @Accessors(chain = true) public static class OpenAiImageProperties { + private boolean enable = false; /** @@ -109,6 +110,7 @@ public class YudaoAiProperties { * 风格 */ private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID; + } @Data diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageModelEnum.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageModelEnum.java similarity index 89% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageModelEnum.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageModelEnum.java index 635c62bba..ea2767fcd 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageModelEnum.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageModelEnum.java @@ -1,8 +1,9 @@ -package org.springframework.ai.models.openai.enums; +package cn.iocoder.yudao.framework.ai.core.enums; import lombok.AllArgsConstructor; import lombok.Getter; +// TODO 芋艿:待梳理 /** * open ai * diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageStyleEnum.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageStyleEnum.java similarity index 92% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageStyleEnum.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageStyleEnum.java index d7999cd72..40cbdfc02 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/enums/OpenAiImageStyleEnum.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/OpenAiImageStyleEnum.java @@ -1,8 +1,9 @@ -package org.springframework.ai.models.openai.enums; +package cn.iocoder.yudao.framework.ai.core.enums; import lombok.AllArgsConstructor; import lombok.Getter; +// TODO 芋艿:待梳理 /** * open ai image style * diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatException.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/exception/ChatException.java similarity index 78% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatException.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/exception/ChatException.java index bc9222699..54e50b665 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatException.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/exception/ChatException.java @@ -1,4 +1,4 @@ -package org.springframework.ai.chat; +package cn.iocoder.yudao.framework.ai.core.exception; /** * 聊天异常 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/package-info.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/package-info.java similarity index 95% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/package-info.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/package-info.java index b38419f6f..a132fdfc5 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/package-info.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/package-info.java @@ -12,4 +12,4 @@ * 2.4 openai 包:【OpenAI】ChatGPT,拷贝 spring-ai 提供的 models/openai 包 * 2.5 midjourney 包:Midjourney,参考 https://github.com/novicezk/midjourney-proxy 实现 */ -package org.springframework.ai; \ No newline at end of file +package cn.iocoder.yudao.framework.ai; \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatClient.java deleted file mode 100644 index bd6aa3e56..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatClient.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat; - - -import org.springframework.ai.chat.messages.UserMessage; -import org.springframework.ai.chat.prompt.Prompt; -import org.springframework.ai.model.ModelClient; - -@FunctionalInterface -public interface ChatClient extends ModelClient { - - default String call(String message) { - Prompt prompt = new Prompt(new UserMessage(message)); - Generation generation = call(prompt).getResult(); - return (generation != null) ? generation.getOutput().getContent() : ""; - } - - @Override - ChatResponse call(Prompt prompt); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatResponse.java deleted file mode 100644 index 641212b97..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/ChatResponse.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.chat; - -import org.springframework.ai.chat.metadata.ChatResponseMetadata; -import org.springframework.ai.model.ModelResponse; -import org.springframework.util.CollectionUtils; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * 人工智能提供商返回的聊天完成(例如生成)响应。 - * - * The chat completion (e.g. generation) response returned by an AI provider. - */ -public class ChatResponse implements ModelResponse { - - private final ChatResponseMetadata chatResponseMetadata; - - /** - * List of generated messages returned by the AI provider. - */ - private final List generations; - - /** - * Construct a new {@link ChatResponse} instance without metadata. - * @param generations the {@link List} of {@link Generation} returned by the AI - * provider. - */ - public ChatResponse(List generations) { - this(generations, ChatResponseMetadata.NULL); - } - - /** - * Construct a new {@link ChatResponse} instance. - * @param generations the {@link List} of {@link Generation} returned by the AI - * provider. - * @param chatResponseMetadata {@link ChatResponseMetadata} containing information - * about the use of the AI provider's API. - */ - public ChatResponse(List generations, ChatResponseMetadata chatResponseMetadata) { - this.chatResponseMetadata = chatResponseMetadata; -// this.generations = List.copyOf(generations); - this.generations = Collections.unmodifiableList(generations); - } - - /** - * The {@link List} of {@link Generation generated outputs}. - *

- * It is a {@link List} of {@link List lists} because the Prompt could request - * multiple output {@link Generation generations}. - * @return the {@link List} of {@link Generation generated outputs}. - */ - - @Override - public List getResults() { - return this.generations; - } - - /** - * @return Returns the first {@link Generation} in the generations list. - */ - public Generation getResult() { - if (CollectionUtils.isEmpty(this.generations)) { - return null; - } - return this.generations.get(0); - } - - /** - * @return Returns {@link ChatResponseMetadata} containing information about the use - * of the AI provider's API. - */ - @Override - public ChatResponseMetadata getMetadata() { - return this.chatResponseMetadata; - } - - @Override - public String toString() { - return "ChatResponse [metadata=" + chatResponseMetadata + ", generations=" + generations + "]"; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; -// if (!(o instanceof ChatResponse that)) -// return false; - if (!(o instanceof ChatResponse)) { - return false; - } - ChatResponse that = (ChatResponse) o; - return Objects.equals(chatResponseMetadata, that.chatResponseMetadata) - && Objects.equals(generations, that.generations); - } - - @Override - public int hashCode() { - return Objects.hash(chatResponseMetadata, generations); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/Generation.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/Generation.java deleted file mode 100644 index ca1784835..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/Generation.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat; - -import org.springframework.ai.chat.messages.AssistantMessage; -import org.springframework.ai.chat.metadata.ChatGenerationMetadata; -import org.springframework.ai.model.ModelResult; -import org.springframework.lang.Nullable; - -import java.util.Map; -import java.util.Objects; - -/** - * 表示AI返回的响应。 - * - * Represents a response returned by the AI. - */ -public class Generation implements ModelResult { - - private AssistantMessage assistantMessage; - - private ChatGenerationMetadata chatGenerationMetadata; - - public Generation(String text) { - this.assistantMessage = new AssistantMessage(text); - } - - public Generation(String text, Map properties) { - this.assistantMessage = new AssistantMessage(text, properties); - } - - @Override - public AssistantMessage getOutput() { - return this.assistantMessage; - } - - @Override - public ChatGenerationMetadata getMetadata() { - ChatGenerationMetadata chatGenerationMetadata = this.chatGenerationMetadata; - return chatGenerationMetadata != null ? chatGenerationMetadata : ChatGenerationMetadata.NULL; - } - - public Generation withGenerationMetadata(@Nullable ChatGenerationMetadata chatGenerationMetadata) { - this.chatGenerationMetadata = chatGenerationMetadata; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - - if (!(o instanceof Generation)) { - return false; - } - Generation that = (Generation) o; - return Objects.equals(assistantMessage, that.assistantMessage) - && Objects.equals(chatGenerationMetadata, that.chatGenerationMetadata); - } - - @Override - public int hashCode() { - return Objects.hash(assistantMessage, chatGenerationMetadata); - } - - @Override - public String toString() { - return "Generation{" + "assistantMessage=" + assistantMessage + ", chatGenerationMetadata=" - + chatGenerationMetadata + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/StreamingChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/StreamingChatClient.java deleted file mode 100644 index 079989db4..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/StreamingChatClient.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat; - -import org.springframework.ai.chat.prompt.Prompt; -import org.springframework.ai.model.StreamingModelClient; -import reactor.core.publisher.Flux; - -@FunctionalInterface -public interface StreamingChatClient extends StreamingModelClient { - - @Override - Flux stream(Prompt prompt); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java deleted file mode 100644 index 7cc936072..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AbstractMessage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import org.springframework.core.io.Resource; -import org.springframework.util.Assert; -import org.springframework.util.StreamUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public abstract class AbstractMessage implements Message { - - protected final MessageType messageType; - - protected final String textContent; - - protected final List mediaData; - - /** - * Additional options for the message to influence the response, not a generative map. - */ - protected final Map properties; - - protected AbstractMessage(MessageType messageType, String content) { - this(messageType, content, Map.of()); - } - - protected AbstractMessage(MessageType messageType, String content, Map messageProperties) { - Assert.notNull(messageType, "Message type must not be null"); - // Assert.notNull(content, "Content must not be null"); - this.messageType = messageType; - this.textContent = content; - this.mediaData = new ArrayList<>(); - this.properties = messageProperties; - } - - protected AbstractMessage(MessageType messageType, String textContent, List mediaData) { - this(messageType, textContent, mediaData, Map.of()); - } - - protected AbstractMessage(MessageType messageType, String textContent, List mediaData, - Map messageProperties) { - - Assert.notNull(messageType, "Message type must not be null"); - Assert.notNull(textContent, "Content must not be null"); - Assert.notNull(mediaData, "media data must not be null"); - - this.messageType = messageType; - this.textContent = textContent; - this.mediaData = new ArrayList<>(mediaData); - this.properties = messageProperties; - } - - protected AbstractMessage(MessageType messageType, Resource resource) { - this(messageType, resource, Collections.emptyMap()); - } - - @SuppressWarnings("null") - protected AbstractMessage(MessageType messageType, Resource resource, Map messageProperties) { - Assert.notNull(messageType, "Message type must not be null"); - Assert.notNull(resource, "Resource must not be null"); - - this.messageType = messageType; - this.properties = messageProperties; - this.mediaData = new ArrayList<>(); - - try (InputStream inputStream = resource.getInputStream()) { - this.textContent = StreamUtils.copyToString(inputStream, Charset.defaultCharset()); - } - catch (IOException ex) { - throw new RuntimeException("Failed to read resource", ex); - } - } - - @Override - public String getContent() { - return this.textContent; - } - - @Override - public List getMediaData() { - return this.mediaData; - } - - @Override - public Map getProperties() { - return this.properties; - } - - @Override - public MessageType getMessageType() { - return this.messageType; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mediaData == null) ? 0 : mediaData.hashCode()); - result = prime * result + ((properties == null) ? 0 : properties.hashCode()); - result = prime * result + ((messageType == null) ? 0 : messageType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AbstractMessage other = (AbstractMessage) obj; - if (mediaData == null) { - if (other.mediaData != null) - return false; - } - else if (!mediaData.equals(other.mediaData)) - return false; - if (properties == null) { - if (other.properties != null) - return false; - } - else if (!properties.equals(other.properties)) - return false; - if (messageType != other.messageType) - return false; - return true; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java deleted file mode 100644 index 28710db1c..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import java.util.Map; - -/** - * 让生成人员知道内容是作为对用户的响应生成的。 - * 此角色指示生成者先前在会话中生成的消息。 - * 通过包括该系列中的辅助消息,您可以为生成的关于提供上下文之前在谈话中的交流。 - * - * Lets the generative know the content was generated as a response to the user. This role - * indicates messages that the generative has previously generated in the conversation. By - * including assistant messages in the series, you provide context to the generative about - * prior exchanges in the conversation. - */ -public class AssistantMessage extends AbstractMessage { - - public AssistantMessage(String content) { - super(MessageType.ASSISTANT, content); - } - - public AssistantMessage(String content, Map properties) { - super(MessageType.ASSISTANT, content, properties); - } - - @Override - public String toString() { - return "AssistantMessage{" + "content='" + getContent() + '\'' + ", properties=" + properties + ", messageType=" - + messageType + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java deleted file mode 100644 index 194aa54af..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/ChatMessage.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import java.util.Map; - -public class ChatMessage extends AbstractMessage { - - public ChatMessage(String role, String content) { - super(MessageType.valueOf(role), content); - } - - public ChatMessage(String role, String content, Map properties) { - super(MessageType.valueOf(role), content, properties); - } - - public ChatMessage(MessageType messageType, String content) { - super(messageType, content); - } - - public ChatMessage(MessageType messageType, String content, Map properties) { - super(messageType, content, properties); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java deleted file mode 100644 index 1faba6a79..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/FunctionMessage.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2023-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import java.util.Map; - -public class FunctionMessage extends AbstractMessage { - - public FunctionMessage(String content) { - super(MessageType.SYSTEM, content); - } - - public FunctionMessage(String content, Map properties) { - super(MessageType.SYSTEM, content, properties); - } - - @Override - public String toString() { - return "FunctionMessage{" + "content='" + getContent() + '\'' + ", properties=" + properties + ", messageType=" - + messageType + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MediaData.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MediaData.java deleted file mode 100644 index 9acd9b151..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MediaData.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import org.springframework.util.Assert; -import org.springframework.util.MimeType; - -/** - * @author Christian Tzolov - */ -public class MediaData { - - private final MimeType mimeType; - - private final Object data; - - public MediaData(MimeType mimeType, Object data) { - Assert.notNull(mimeType, "MimeType must not be null"); - // Assert.notNull(data, "Data must not be null"); - this.mimeType = mimeType; - this.data = data; - } - - public MimeType getMimeType() { - return this.mimeType; - } - - public Object getData() { - return this.data; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/Message.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/Message.java deleted file mode 100644 index 10c893ad7..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/Message.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import java.util.List; -import java.util.Map; - -public interface Message { - - String getContent(); - - List getMediaData(); - - Map getProperties(); - - MessageType getMessageType(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MessageType.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MessageType.java deleted file mode 100644 index a227c4530..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/MessageType.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.chat.messages; - -public enum MessageType { - - // 用户消息 - USER("user"), - - // 之前会话的消息 - ASSISTANT("assistant"), - - // 根据注释说明:您可以使用系统消息来指示具有生成性,表现得像某个角色或以特定的方式提供答案总体安排 - // 简单理解:在对话前,发送一条具有角色的信息让模型理解(如:你现在是一个10年拍摄经验的导演,拥有丰富的经验。 这样你就可以去问他,怎么拍一个短视频可以在抖音上火) - SYSTEM("system"), - - // 函数?根据引用现在不支持,会抛出一个异常 ---> throw new IllegalArgumentException("Tool execution results are not supported for Bedrock models"); - FUNCTION("function"); - - private final String value; - - MessageType(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public static MessageType fromValue(String value) { - for (MessageType messageType : MessageType.values()) { - if (messageType.getValue().equals(value)) { - return messageType; - } - } - throw new IllegalArgumentException("Invalid MessageType value: " + value); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java deleted file mode 100644 index f8c67f2b4..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/SystemMessage.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import org.springframework.core.io.Resource; - -/** - * 作为输入传递的“system”类型的消息。系统消息给出高级别对话说明。 - * 此角色通常提供高级说明对话。 - * 例如,您可以使用系统消息来指示具有生成性,表现得像某个角色或以特定的方式提供答案总体安排 - * - * A message of the type 'system' passed as input. The system message gives high level - * instructions for the conversation. This role typically provides high-level instructions - * for the conversation. For example, you might use a system message to instruct the - * generative to behave like a certain character or to provide answers in a specific - * format. - */ -public class SystemMessage extends AbstractMessage { - - public SystemMessage(String content) { - super(MessageType.SYSTEM, content); - } - - public SystemMessage(Resource resource) { - super(MessageType.SYSTEM, resource); - } - - @Override - public String toString() { - return "SystemMessage{" + "content='" + getContent() + '\'' + ", properties=" + properties + ", messageType=" - + messageType + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/UserMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/UserMessage.java deleted file mode 100644 index ca7f360c2..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/messages/UserMessage.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.messages; - -import org.springframework.core.io.Resource; - -import java.util.List; - -/** - * 作为输入传递的“user”类型的消息具有用户角色的消息来自最终用户或开发者。 - * 它们表示问题、提示或您想要的任何输入产生反应的。 - * - * A message of the type 'user' passed as input Messages with the user role are from the - * end-user or developer. They represent questions, prompts, or any input that you want - * the generative to respond to. - */ -public class UserMessage extends AbstractMessage { - - public UserMessage(String message) { - super(MessageType.USER, message); - } - - public UserMessage(Resource resource) { - super(MessageType.USER, resource); - } - - public UserMessage(String textContent, List mediaDataList) { - super(MessageType.USER, textContent, mediaDataList); - } - - @Override - public String toString() { - return "UserMessage{" + "content='" + getContent() + '\'' + ", properties=" + properties + ", messageType=" - + messageType + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java deleted file mode 100644 index d9f5fc56e..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatGenerationMetadata.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - -import org.springframework.ai.model.ResultMetadata; -import org.springframework.lang.Nullable; - -/** - * Abstract Data Type (ADT) encapsulating information on the completion choices in the AI - * response. - * - * @author John Blum - * @since 0.7.0 - */ -public interface ChatGenerationMetadata extends ResultMetadata { - - ChatGenerationMetadata NULL = ChatGenerationMetadata.from(null, null); - - /** - * Factory method used to construct a new {@link ChatGenerationMetadata} from the - * given {@link String finish reason} and content filter metadata. - * @param finishReason {@link String} contain the reason for the choice completion. - * @param contentFilterMetadata underlying AI provider metadata for filtering applied - * to generation content. - * @return a new {@link ChatGenerationMetadata} from the given {@link String finish - * reason} and content filter metadata. - */ - static ChatGenerationMetadata from(String finishReason, Object contentFilterMetadata) { - return new ChatGenerationMetadata() { - - @Override - @SuppressWarnings("unchecked") - public T getContentFilterMetadata() { - return (T) contentFilterMetadata; - } - - @Override - public String getFinishReason() { - return finishReason; - } - }; - } - - /** - * Returns the underlying AI provider metadata for filtering applied to generation - * content. - * @param {@link Class Type} used to cast the filtered content metadata into the - * AI provider-specific type. - * @return the underlying AI provider metadata for filtering applied to generation - * content. - */ - @Nullable - T getContentFilterMetadata(); - - /** - * Get the {@link String reason} this choice completed for the generation. - * @return the {@link String reason} this choice completed for the generation. - */ - String getFinishReason(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java deleted file mode 100644 index 38eb1fd59..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/ChatResponseMetadata.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - - -import org.springframework.ai.model.ResponseMetadata; - -/** - * Abstract Data Type (ADT) modeling common AI provider metadata returned in an AI - * response. - * - * 抽象数据类型(ADT)建模AI响应中返回的常见AI提供者元数据。 - * - * @author John Blum - * @since 0.7.0 - */ -public interface ChatResponseMetadata extends ResponseMetadata { - - ChatResponseMetadata NULL = new ChatResponseMetadata() { - }; - - /** - * Returns AI provider specific metadata on rate limits. - * @return AI provider specific metadata on rate limits. - * @see RateLimit - */ - default RateLimit getRateLimit() { - return new EmptyRateLimit(); - } - - /** - * Returns AI provider specific metadata on API usage. - * @return AI provider specific metadata on API usage. - * @see Usage - */ - default Usage getUsage() { - return new EmptyUsage(); - } - - default PromptMetadata getPromptMetadata() { - return PromptMetadata.empty(); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java deleted file mode 100644 index 480a94d3e..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyRateLimit.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - -import java.time.Duration; - -/** - * A RateLimit implementation that returns zero for all property getters - * - * @author John Blum - * @since 0.7.0 - */ -public class EmptyRateLimit implements RateLimit { - - @Override - public Long getRequestsLimit() { - return 0L; - } - - @Override - public Long getRequestsRemaining() { - return 0L; - } - - @Override - public Duration getRequestsReset() { - return Duration.ZERO; - } - - @Override - public Long getTokensLimit() { - return 0L; - } - - @Override - public Long getTokensRemaining() { - return 0L; - } - - @Override - public Duration getTokensReset() { - return Duration.ZERO; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java deleted file mode 100644 index 027e30279..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/EmptyUsage.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - -/** - * A EmpytUsage implementation that returns zero for all property getters - * - * @author John Blum - * @since 0.7.0 - */ -public class EmptyUsage implements Usage { - - @Override - public Long getPromptTokens() { - return 0L; - } - - @Override - public Long getGenerationTokens() { - return 0L; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java deleted file mode 100644 index becb12ded..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/PromptMetadata.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.chat.metadata; - -import org.springframework.util.Assert; - -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.StreamSupport; - -/** - * Abstract Data Type (ADT) modeling metadata gathered by the AI during request - * processing. - * - * @author John Blum - * @since 0.7.0 - */ -@FunctionalInterface -public interface PromptMetadata extends Iterable { - - /** - * Factory method used to create empty {@link PromptMetadata} when the information is - * not supplied by the AI provider. - * @return empty {@link PromptMetadata}. - */ - static PromptMetadata empty() { - return of(); - } - - /** - * Factory method used to create a new {@link PromptMetadata} composed of an array of - * {@link PromptFilterMetadata}. - * @param array array of {@link PromptFilterMetadata} used to compose the - * {@link PromptMetadata}. - * @return a new {@link PromptMetadata} composed of an array of - * {@link PromptFilterMetadata}. - */ - static PromptMetadata of(PromptFilterMetadata... array) { - return of(Arrays.asList(array)); - } - - /** - * Factory method used to create a new {@link PromptMetadata} composed of an - * {@link Iterable} of {@link PromptFilterMetadata}. - * @param iterable {@link Iterable} of {@link PromptFilterMetadata} used to compose - * the {@link PromptMetadata}. - * @return a new {@link PromptMetadata} composed of an {@link Iterable} of - * {@link PromptFilterMetadata}. - */ - static PromptMetadata of(Iterable iterable) { - Assert.notNull(iterable, "An Iterable of PromptFilterMetadata must not be null"); - return iterable::iterator; - } - - /** - * Returns an {@link Optional} {@link PromptFilterMetadata} at the given index. - * @param promptIndex index of the {@link PromptFilterMetadata} contained in this - * {@link PromptMetadata}. - * @return {@link Optional} {@link PromptFilterMetadata} at the given index. - * @throws IllegalArgumentException if the prompt index is less than 0. - */ - default Optional findByPromptIndex(int promptIndex) { - - Assert.isTrue(promptIndex > -1, "Prompt index [%d] must be greater than equal to 0".formatted(promptIndex)); - - return StreamSupport.stream(this.spliterator(), false) - .filter(promptFilterMetadata -> promptFilterMetadata.getPromptIndex() == promptIndex) - .findFirst(); - } - - /** - * Abstract Data Type (ADT) modeling filter metadata for all prompts sent during an AI - * request. - */ - interface PromptFilterMetadata { - - /** - * Factory method used to construct a new {@link PromptFilterMetadata} with the - * given prompt index and content filter metadata. - * @param promptIndex index of the prompt filter metadata contained in the AI - * response. - * @param contentFilterMetadata underlying AI provider metadata for filtering - * applied to prompt content. - * @return a new instance of {@link PromptFilterMetadata} with the given prompt - * index and content filter metadata. - */ - static PromptFilterMetadata from(int promptIndex, Object contentFilterMetadata) { - - return new PromptFilterMetadata() { - - @Override - public int getPromptIndex() { - return promptIndex; - } - - @Override - @SuppressWarnings("unchecked") - public T getContentFilterMetadata() { - return (T) contentFilterMetadata; - } - }; - } - - /** - * Index of the prompt filter metadata contained in the AI response. - * @return an {@link Integer index} fo the prompt filter metadata contained in the - * AI response. - */ - int getPromptIndex(); - - /** - * Returns the underlying AI provider metadata for filtering applied to prompt - * content. - * @param {@link Class Type} used to cast the filtered content metadata into - * the AI provider-specific type. - * @return the underlying AI provider metadata for filtering applied to prompt - * content. - */ - T getContentFilterMetadata(); - - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java deleted file mode 100644 index 22dd64b18..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/RateLimit.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - -import java.time.Duration; - -/** - * Abstract Data Type (ADT) encapsulating metadata from an AI provider's API rate limits - * granted to the API key in use and the API key's current balance. - * - * @author John Blum - * @since 0.7.0 - */ -public interface RateLimit { - - /** - * Returns the maximum number of requests that are permitted before exhausting the - * rate limit. - * @return an {@link Long} with the maximum number of requests that are permitted - * before exhausting the rate limit. - * @see #getRequestsRemaining() - */ - Long getRequestsLimit(); - - /** - * Returns the remaining number of requests that are permitted before exhausting the - * {@link #getRequestsLimit() rate limit}. - * @return an {@link Long} with the remaining number of requests that are permitted - * before exhausting the {@link #getRequestsLimit() rate limit}. - * @see #getRequestsLimit() - */ - Long getRequestsRemaining(); - - /** - * Returns the {@link Duration time} until the rate limit (based on requests) resets - * to its {@link #getRequestsLimit() initial state}. - * @return a {@link Duration} representing the time until the rate limit (based on - * requests) resets to its {@link #getRequestsLimit() initial state}. - * @see #getRequestsLimit() - */ - Duration getRequestsReset(); - - /** - * Returns the maximum number of tokens that are permitted before exhausting the rate - * limit. - * @return an {@link Long} with the maximum number of tokens that are permitted before - * exhausting the rate limit. - * @see #getTokensRemaining() - */ - Long getTokensLimit(); - - /** - * Returns the remaining number of tokens that are permitted before exhausting the - * {@link #getTokensLimit() rate limit}. - * @return an {@link Long} with the remaining number of tokens that are permitted - * before exhausting the {@link #getTokensLimit() rate limit}. - * @see #getTokensLimit() - */ - Long getTokensRemaining(); - - /** - * Returns the {@link Duration time} until the rate limit (based on tokens) resets to - * its {@link #getTokensLimit() initial state}. - * @return a {@link Duration} with the time until the rate limit (based on tokens) - * resets to its {@link #getTokensLimit() initial state}. - * @see #getTokensLimit() - */ - Duration getTokensReset(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/Usage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/Usage.java deleted file mode 100644 index de4fb9ac6..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/metadata/Usage.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.metadata; - -/** - * 抽象数据类型(ADT)封装关于人工智能提供商API使用的元数据根据AI请求。 - * - * Abstract Data Type (ADT) encapsulating metadata on the usage of an AI provider's API - * per AI request. - * - * @author John Blum - * @since 0.7.0 - */ -public interface Usage { - - /** - * 返回AI请求的{@literal prompt}中使用的令牌数。 - * @返回一个{@link Long},其中包含在的{@literal提示符}中使用的令牌数AI请求。 - * - * Returns the number of tokens used in the {@literal prompt} of the AI request. - * @return an {@link Long} with the number of tokens used in the {@literal prompt} of - * the AI request. - * @see #getGenerationTokens() - */ - Long getPromptTokens(); - - /** - * Returns the number of tokens returned in the {@literal generation (aka completion)} - * of the AI's response. - * @return an {@link Long} with the number of tokens returned in the - * {@literal generation (aka completion)} of the AI's response. - * @see #getPromptTokens() - */ - Long getGenerationTokens(); - - /** - * Return the total number of tokens from both the {@literal prompt} of an AI request - * and {@literal generation} of the AI's response. - * @return the total number of tokens from both the {@literal prompt} of an AI request - * and {@literal generation} of the AI's response. - * @see #getPromptTokens() - * @see #getGenerationTokens() - */ - default Long getTotalTokens() { - Long promptTokens = getPromptTokens(); - promptTokens = promptTokens != null ? promptTokens : 0; - Long completionTokens = getGenerationTokens(); - completionTokens = completionTokens != null ? completionTokens : 0; - return promptTokens + completionTokens; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/package-info.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/package-info.java deleted file mode 100644 index 98d92eb71..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * The org.sf.ai.chat package represents the bounded context for the Chat Model within the - * AI generative model domain. This package extends the core domain defined in - * org.sf.ai.generative, providing implementations specific to chat-based generative AI - * interactions. - * - * In line with Domain-Driven Design principles, this package includes implementations of - * entities and value objects specific to the chat context, such as ChatPrompt and - * ChatResponse, adhering to the ubiquitous language of chat interactions in AI models. - * - * This bounded context is designed to encapsulate all aspects of chat-based AI - * functionalities, maintaining a clear boundary from other contexts within the AI domain. - */ -package org.springframework.ai.chat; \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java deleted file mode 100644 index ae6373cf1..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/AssistantPromptTemplate.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.AssistantMessage; -import org.springframework.ai.chat.messages.Message; -import org.springframework.core.io.Resource; - -import java.util.Map; - -public class AssistantPromptTemplate extends PromptTemplate { - - public AssistantPromptTemplate(String template) { - super(template); - } - - public AssistantPromptTemplate(Resource resource) { - super(resource); - } - - @Override - public Prompt create() { - return new Prompt(new AssistantMessage(render())); - } - - @Override - public Prompt create(Map model) { - return new Prompt(new AssistantMessage(render(model))); - } - - @Override - public Message createMessage() { - return new AssistantMessage(render()); - } - - @Override - public Message createMessage(Map model) { - return new AssistantMessage(render(model)); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java deleted file mode 100644 index 5c45a37ba..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.model.ModelOptions; - -/** - * 聊天选项代表了常见的选项,可在不同的聊天模式中移植。 - * - * The ChatOptions represent the common options, portable across different chat models. - */ -public interface ChatOptions extends ModelOptions { - - Float getTemperature(); - - void setTemperature(Float temperature); - - Float getTopP(); - - void setTopP(Float topP); - - Integer getTopK(); - - void setTopK(Integer topK); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java deleted file mode 100644 index f702f6350..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatOptionsBuilder.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -public class ChatOptionsBuilder { - - private class ChatOptionsImpl implements ChatOptions { - - private Float temperature; - - private Float topP; - - private Integer topK; - - @Override - public Float getTemperature() { - return temperature; - } - - @Override - public void setTemperature(Float temperature) { - this.temperature = temperature; - } - - @Override - public Float getTopP() { - return topP; - } - - @Override - public void setTopP(Float topP) { - this.topP = topP; - } - - @Override - public Integer getTopK() { - return topK; - } - - @Override - public void setTopK(Integer topK) { - this.topK = topK; - } - - } - - private final ChatOptionsImpl options = new ChatOptionsImpl(); - - private ChatOptionsBuilder() { - } - - public static ChatOptionsBuilder builder() { - return new ChatOptionsBuilder(); - } - - public ChatOptionsBuilder withTemperature(Float temperature) { - options.setTemperature(temperature); - return this; - } - - public ChatOptionsBuilder withTopP(Float topP) { - options.setTopP(topP); - return this; - } - - public ChatOptionsBuilder withTopK(Integer topK) { - options.setTopK(topK); - return this; - } - - public ChatOptions build() { - return options; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java deleted file mode 100644 index 15f9ca5d4..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/ChatPromptTemplate.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * PromptTemplate,用于将角色指定为字符串实现及其角色不足以满足您的需求。 - * - * A PromptTemplate that lets you specify the role as a string should the current - * implementations and their roles not suffice for your needs. - */ -public class ChatPromptTemplate implements PromptTemplateActions, PromptTemplateChatActions { - - private final List promptTemplates; - - public ChatPromptTemplate(List promptTemplates) { - this.promptTemplates = promptTemplates; - } - - @Override - public String render() { - StringBuilder sb = new StringBuilder(); - for (PromptTemplate promptTemplate : promptTemplates) { - sb.append(promptTemplate.render()); - } - return sb.toString(); - } - - @Override - public String render(Map model) { - StringBuilder sb = new StringBuilder(); - for (PromptTemplate promptTemplate : promptTemplates) { - sb.append(promptTemplate.render(model)); - } - return sb.toString(); - } - - @Override - public List createMessages() { - List messages = new ArrayList<>(); - for (PromptTemplate promptTemplate : promptTemplates) { - messages.add(promptTemplate.createMessage()); - } - return messages; - } - - @Override - public List createMessages(Map model) { - List messages = new ArrayList<>(); - for (PromptTemplate promptTemplate : promptTemplates) { - messages.add(promptTemplate.createMessage(model)); - } - return messages; - } - - @Override - public Prompt create() { - List messages = createMessages(); - return new Prompt(messages); - } - - @Override - public Prompt create(Map model) { - List messages = createMessages(model); - return new Prompt(messages); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java deleted file mode 100644 index 4c7ce981f..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/FunctionPromptTemplate.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -public class FunctionPromptTemplate extends PromptTemplate { - - private String name; - - public FunctionPromptTemplate(String template) { - super(template); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/Prompt.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/Prompt.java deleted file mode 100644 index a598b3c35..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/Prompt.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; -import org.springframework.ai.chat.messages.UserMessage; -import org.springframework.ai.model.ModelOptions; -import org.springframework.ai.model.ModelRequest; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * 文字内容 - */ -public class Prompt implements ModelRequest> { - - private final List messages; - - private ChatOptions modelOptions; - - public Prompt(String contents) { - this(new UserMessage(contents)); - } - - public Prompt(Message message) { - this(Collections.singletonList(message)); - } - - public Prompt(List messages) { - this.messages = messages; - } - - public Prompt(String contents, ChatOptions modelOptions) { - this(new UserMessage(contents), modelOptions); - } - - public Prompt(Message message, ChatOptions modelOptions) { - this(Collections.singletonList(message), modelOptions); - } - - public Prompt(List messages, ChatOptions modelOptions) { - this.messages = messages; - this.modelOptions = modelOptions; - } - - public String getContents() { - StringBuilder sb = new StringBuilder(); - for (Message message : getInstructions()) { - sb.append(message.getContent()); - } - return sb.toString(); - } - - @Override - public ModelOptions getOptions() { - return this.modelOptions; - } - - @Override - public List getInstructions() { - return this.messages; - } - - @Override - public String toString() { - return "Prompt{" + "messages=" + this.messages + ", modelOptions=" + this.modelOptions + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; -// if (!(o instanceof Prompt prompt)) -// return false; - if (!(o instanceof Prompt)) { - return false; - } - Prompt prompt = (Prompt) o; - return Objects.equals(this.messages, prompt.messages) && Objects.equals(this.modelOptions, prompt.modelOptions); - } - - @Override - public int hashCode() { - return Objects.hash(this.messages, this.modelOptions); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java deleted file mode 100644 index f1e910da0..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplate.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; -import org.springframework.ai.chat.messages.UserMessage; -import org.springframework.ai.parser.OutputParser; -import org.antlr.runtime.Token; -import org.antlr.runtime.TokenStream; -import org.springframework.core.io.Resource; -import org.springframework.util.StreamUtils; -import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.compiler.STLexer; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -/** - * 用户输入的提示内容模板 - * - * 实现:提示词模板操作 提示词模板message相关操作 - */ -public class PromptTemplate implements PromptTemplateActions, PromptTemplateMessageActions { - - private ST st; - - private Map dynamicModel = new HashMap<>(); - - protected String template; - - protected TemplateFormat templateFormat = TemplateFormat.ST; - - private OutputParser outputParser; - - public PromptTemplate(Resource resource) { - try (InputStream inputStream = resource.getInputStream()) { - this.template = StreamUtils.copyToString(inputStream, Charset.defaultCharset()); - } - catch (IOException ex) { - throw new RuntimeException("Failed to read resource", ex); - } - try { - this.st = new ST(this.template, '{', '}'); - } - catch (Exception ex) { - throw new IllegalArgumentException("The template string is not valid.", ex); - } - } - - public PromptTemplate(String template) { - this.template = template; - // If the template string is not valid, an exception will be thrown - try { - this.st = new ST(this.template, '{', '}'); - } - catch (Exception ex) { - throw new IllegalArgumentException("The template string is not valid.", ex); - } - } - - public PromptTemplate(String template, Map model) { - this.template = template; - // If the template string is not valid, an exception will be thrown - try { - this.st = new ST(this.template, '{', '}'); - for (Entry entry : model.entrySet()) { - add(entry.getKey(), entry.getValue()); - dynamicModel.put(entry.getKey(), entry.getValue()); - } - } - catch (Exception ex) { - throw new IllegalArgumentException("The template string is not valid.", ex); - } - } - - public PromptTemplate(Resource resource, Map model) { - try (InputStream inputStream = resource.getInputStream()) { - this.template = StreamUtils.copyToString(inputStream, Charset.defaultCharset()); - } - catch (IOException ex) { - throw new RuntimeException("Failed to read resource", ex); - } - // If the template string is not valid, an exception will be thrown - try { - this.st = new ST(this.template, '{', '}'); - for (Entry entry : model.entrySet()) { - add(entry.getKey(), entry.getValue()); - dynamicModel.put(entry.getKey(), entry.getValue()); - } - } - catch (Exception ex) { - throw new IllegalArgumentException("The template string is not valid.", ex); - } - } - - public OutputParser getOutputParser() { - return outputParser; - } - - public void setOutputParser(OutputParser outputParser) { - Objects.requireNonNull(outputParser, "Output Parser can not be null"); - this.outputParser = outputParser; - } - - public void add(String name, Object value) { - this.st.add(name, value); - this.dynamicModel.put(name, value); - } - - public String getTemplate() { - return this.template; - } - - public TemplateFormat getTemplateFormat() { - return this.templateFormat; - } - - // Render Methods - @Override - public String render() { - validate(this.dynamicModel); - return st.render(); - } - - @Override - public String render(Map model) { - validate(model); - for (Entry entry : model.entrySet()) { - if (st.getAttribute(entry.getKey()) != null) { - st.remove(entry.getKey()); - } - if (entry.getValue() instanceof Resource) { - st.add(entry.getKey(), renderResource((Resource) entry.getValue())); - } - else { - st.add(entry.getKey(), entry.getValue()); - } - - } - return st.render(); - } - - private String renderResource(Resource resource) { - try { - return resource.getContentAsString(Charset.defaultCharset()); - } - catch (IOException e) { - throw new RuntimeException(e); - } - // try (InputStream inputStream = resource.getInputStream()) { - // return StreamUtils.copyToString(inputStream, Charset.defaultCharset()); - // } - // catch (IOException ex) { - // throw new RuntimeException(ex); - // } - } - - @Override - public Message createMessage() { - return new UserMessage(render()); - } - - @Override - public Message createMessage(Map model) { - return new UserMessage(render(model)); - } - - @Override - public Prompt create() { - return new Prompt(render(new HashMap<>())); - } - - @Override - public Prompt create(Map model) { - return new Prompt(render(model)); - } - - public Set getInputVariables() { - TokenStream tokens = this.st.impl.tokens; - return IntStream.range(0, tokens.range()) - .mapToObj(tokens::get) - .filter(token -> token.getType() == STLexer.ID) - .map(Token::getText) - .collect(Collectors.toSet()); - } - - protected void validate(Map model) { - Set dynamicVariableNames = new HashSet<>(this.dynamicModel.keySet()); - Set modelVariables = new HashSet<>(model.keySet()); - modelVariables.addAll(dynamicVariableNames); - Set missingEntries = new HashSet<>(getInputVariables()); - missingEntries.removeAll(modelVariables); - if (!missingEntries.isEmpty()) { - throw new IllegalStateException( - "All template variables were not replaced. Missing variable names are " + missingEntries); - } - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java deleted file mode 100644 index 8097e3f35..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateActions.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import java.util.Map; - -/** - * 提示词模板操作 - */ -public interface PromptTemplateActions extends PromptTemplateStringActions { - - /** - * 创建 Prompt - * @return - */ - Prompt create(); - - Prompt create(Map model); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java deleted file mode 100644 index 24d9f908c..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateChatActions.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; - -import java.util.List; -import java.util.Map; - -/** - * 聊天操作 - * - */ -public interface PromptTemplateChatActions { - - List createMessages(); - - List createMessages(Map model); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java deleted file mode 100644 index 17ff49286..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateMessageActions.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; - -import java.util.Map; - -/** - * 用户输入的提示内容 模板信息操作 - */ -public interface PromptTemplateMessageActions { - - /** - * 创建一个 message - * @return - */ - Message createMessage(); - - /** - * 创建一个 message - * @return - */ - Message createMessage(Map model); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java deleted file mode 100644 index 0cd9df3b2..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/PromptTemplateStringActions.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.ai.chat.prompt; - -import java.util.Map; - -/** - * 提示次模板字符串操作 - */ -public interface PromptTemplateStringActions { - - String render(); - - String render(Map model); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java deleted file mode 100644 index 539287d07..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/SystemPromptTemplate.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -import org.springframework.ai.chat.messages.Message; -import org.springframework.ai.chat.messages.SystemMessage; -import org.springframework.core.io.Resource; - -import java.util.Map; - -public class SystemPromptTemplate extends PromptTemplate { - - public SystemPromptTemplate(String template) { - super(template); - } - - public SystemPromptTemplate(Resource resource) { - super(resource); - } - - @Override - public Message createMessage() { - return new SystemMessage(render()); - } - - @Override - public Message createMessage(Map model) { - return new SystemMessage(render(model)); - } - - @Override - public Prompt create() { - return new Prompt(new SystemMessage(render())); - } - - @Override - public Prompt create(Map model) { - return new Prompt(new SystemMessage(render(model))); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java deleted file mode 100644 index 1001ee266..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/chat/prompt/TemplateFormat.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.chat.prompt; - -public enum TemplateFormat { - - ST("ST"); - - private final String value; - - TemplateFormat(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - public static TemplateFormat fromValue(String value) { - for (TemplateFormat templateFormat : TemplateFormat.values()) { - if (templateFormat.getValue().equals(value)) { - return templateFormat; - } - } - throw new IllegalArgumentException("Invalid TemplateFormat value: " + value); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/Image.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/Image.java deleted file mode 100644 index 3c6ae1ea1..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/Image.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import java.util.Objects; - -public class Image { - - /** - * 可以访问图像的URL。 - * - * The URL where the image can be accessed. - */ - private String url; - - /** - * Base64编码的图像字符串。 - * - * Base64 encoded image string. - */ - private String b64Json; - - public Image(String url, String b64Json) { - this.url = url; - this.b64Json = b64Json; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getB64Json() { - return b64Json; - } - - public void setB64Json(String b64Json) { - this.b64Json = b64Json; - } - - @Override - public String toString() { - return "Image{" + "url='" + url + '\'' + ", b64Json='" + b64Json + '\'' + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof Image image)) - return false; - return Objects.equals(url, image.url) && Objects.equals(b64Json, image.b64Json); - } - - @Override - public int hashCode() { - return Objects.hash(url, b64Json); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageClient.java deleted file mode 100644 index 1993fbe92..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageClient.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - - -import org.springframework.ai.model.ModelClient; - -public interface ImageClient extends ModelClient { - - /** - * 跟 chat一样 - * @param imagePrompt the request object to be sent to the AI model - * @return - */ - ImageResponse call(ImagePrompt imagePrompt); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGeneration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGeneration.java deleted file mode 100644 index 924f5872a..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGeneration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - - -import org.springframework.ai.model.ModelResult; - -public class ImageGeneration implements ModelResult { - - // metadata 信息为空现在 - private ImageGenerationMetadata imageGenerationMetadata; - - private Image image; - - public ImageGeneration(Image image) { - this.image = image; - } - - public ImageGeneration(Image image, ImageGenerationMetadata imageGenerationMetadata) { - this.image = image; - this.imageGenerationMetadata = imageGenerationMetadata; - } - - @Override - public Image getOutput() { - return image; - } - - @Override - public ImageGenerationMetadata getMetadata() { - return imageGenerationMetadata; - } - - @Override - public String toString() { - return "ImageGeneration{" + "imageGenerationMetadata=" + imageGenerationMetadata + ", image=" + image + '}'; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java deleted file mode 100644 index e140aa814..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageGenerationMetadata.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import org.springframework.ai.model.ResultMetadata; - -public interface ImageGenerationMetadata extends ResultMetadata { - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageMessage.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageMessage.java deleted file mode 100644 index 51d378b8c..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageMessage.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import java.util.Objects; - -public class ImageMessage { - - private String text; - - private Float weight; - - public ImageMessage(String text) { - this.text = text; - } - - public ImageMessage(String text, Float weight) { - this.text = text; - this.weight = weight; - } - - public String getText() { - return text; - } - - public Float getWeight() { - return weight; - } - - @Override - public String toString() { - return "mageMessage{" + "text='" + text + '\'' + ", weight=" + weight + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ImageMessage that)) - return false; - return Objects.equals(text, that.text) && Objects.equals(weight, that.weight); - } - - @Override - public int hashCode() { - return Objects.hash(text, weight); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptions.java deleted file mode 100644 index 428376364..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptions.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import org.springframework.ai.model.ModelOptions; - -/** - * ImageOptions represent the common options, portable across different image generation - * models. - */ -public interface ImageOptions extends ModelOptions { - - Integer getN(); - - String getModel(); - - Integer getWidth(); - - Integer getHeight(); - - String getResponseFormat(); // openai - url or base64 : stability ai byte[] or base64 - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java deleted file mode 100644 index 49dc3497d..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageOptionsBuilder.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -public class ImageOptionsBuilder { - - private class ImageModelOptionsImpl implements ImageOptions { - - private Integer n; - - private String model; - - private Integer width; - - private Integer height; - - private String responseFormat; - - @Override - public Integer getN() { - return n; - } - - public void setN(Integer n) { - this.n = n; - } - - @Override - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - @Override - public String getResponseFormat() { - return responseFormat; - } - - public void setResponseFormat(String responseFormat) { - this.responseFormat = responseFormat; - } - - @Override - public Integer getWidth() { - return width; - } - - public void setWidth(Integer width) { - this.width = width; - } - - @Override - public Integer getHeight() { - return height; - } - - public void setHeight(Integer height) { - this.height = height; - } - - } - - private final ImageModelOptionsImpl options = new ImageModelOptionsImpl(); - - private ImageOptionsBuilder() { - - } - - public static ImageOptionsBuilder builder() { - return new ImageOptionsBuilder(); - } - - public ImageOptionsBuilder withN(Integer n) { - options.setN(n); - return this; - } - - public ImageOptionsBuilder withModel(String model) { - options.setModel(model); - return this; - } - - public ImageOptionsBuilder withResponseFormat(String responseFormat) { - options.setResponseFormat(responseFormat); - return this; - } - - public ImageOptionsBuilder withWidth(Integer width) { - options.setWidth(width); - return this; - } - - public ImageOptionsBuilder withHeight(Integer height) { - options.setHeight(height); - return this; - } - - public ImageOptions build() { - return options; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImagePrompt.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImagePrompt.java deleted file mode 100644 index 4f9dcdc59..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImagePrompt.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import org.springframework.ai.model.ModelRequest; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * 图片内容 - */ -public class ImagePrompt implements ModelRequest> { - - private final List messages; - - private ImageOptions imageModelOptions; - - public ImagePrompt(List messages) { - this.messages = messages; - } - - public ImagePrompt(List messages, ImageOptions imageModelOptions) { - this.messages = messages; - this.imageModelOptions = imageModelOptions; - } - - public ImagePrompt(ImageMessage imageMessage, ImageOptions imageOptions) { - this(Collections.singletonList(imageMessage), imageOptions); - } - - public ImagePrompt(String instructions, ImageOptions imageOptions) { - this(new ImageMessage(instructions), imageOptions); - } - - public ImagePrompt(String instructions) { -// this(new ImageMessage(instructions), ImageOptionsBuilder.builder().build()); - this(new ImageMessage(instructions), null); - } - - @Override - public List getInstructions() { - return messages; - } - - @Override - public ImageOptions getOptions() { - return imageModelOptions; - } - - @Override - public String toString() { - return "NewImagePrompt{" + "messages=" + messages + ", imageModelOptions=" + imageModelOptions + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ImagePrompt that)) - return false; - return Objects.equals(messages, that.messages) && Objects.equals(imageModelOptions, that.imageModelOptions); - } - - @Override - public int hashCode() { - return Objects.hash(messages, imageModelOptions); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponse.java deleted file mode 100644 index d3e314526..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponse.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - -import org.springframework.ai.model.ModelResponse; - -import java.util.List; -import java.util.Objects; - -public class ImageResponse implements ModelResponse { - - private final ImageResponseMetadata imageResponseMetadata; - - private final List imageGenerations; - - public ImageResponse(List generations) { - this(generations, ImageResponseMetadata.NULL); - } - - public ImageResponse(List generations, ImageResponseMetadata imageResponseMetadata) { - this.imageResponseMetadata = imageResponseMetadata; - this.imageGenerations = List.copyOf(generations); - } - - @Override - public ImageGeneration getResult() { - return imageGenerations.get(0); - } - - @Override - public List getResults() { - return imageGenerations; - } - - @Override - public ImageResponseMetadata getMetadata() { - return imageResponseMetadata; - } - - @Override - public String toString() { - return "ImageResponse{" + "imageResponseMetadata=" + imageResponseMetadata + ", imageGenerations=" - + imageGenerations + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof ImageResponse that)) - return false; - return Objects.equals(imageResponseMetadata, that.imageResponseMetadata) - && Objects.equals(imageGenerations, that.imageGenerations); - } - - @Override - public int hashCode() { - return Objects.hash(imageResponseMetadata, imageGenerations); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java deleted file mode 100644 index 78fa5e7de..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/image/ImageResponseMetadata.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.image; - - -import org.springframework.ai.model.ResponseMetadata; - -public interface ImageResponseMetadata extends ResponseMetadata { - - ImageResponseMetadata NULL = new ImageResponseMetadata() { - }; - - default Long created() { - return System.currentTimeMillis(); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelClient.java deleted file mode 100644 index 03bec4c70..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelClient.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * The ModelClient interface provides a generic API for invoking AI models. It is designed - * to handle the interaction with various types of AI models by abstracting the process of - * sending requests and receiving responses. The interface uses Java generics to - * accommodate different types of requests and responses, enhancing flexibility and - * adaptability across different AI model implementations. - * - * @param the generic type of the request to the AI model - * @param the generic type of the response from the AI model - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ModelClient, TRes extends ModelResponse> { - - /** - * Executes a method call to the AI model. - * @param request the request object to be sent to the AI model - * @return the response from the AI model - */ - TRes call(TReq request) throws Throwable; - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptions.java deleted file mode 100644 index 96b301b79..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptions.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * Interface representing the customizable options for AI model interactions. This marker - * interface allows for the specification of various settings and parameters that can - * influence the behavior and output of AI models. It is designed to provide flexibility - * and adaptability in different AI scenarios, ensuring that the AI models can be - * fine-tuned according to specific requirements. - * - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ModelOptions { - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java deleted file mode 100644 index 9360399b6..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelOptionsUtils.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.github.victools.jsonschema.generator.*; -import com.github.victools.jsonschema.module.jackson.JacksonModule; -import com.github.victools.jsonschema.module.jackson.JacksonOption; -import com.github.victools.jsonschema.module.swagger2.Swagger2Module; -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - -/** - * Utility class for manipulating {@link ModelOptions} objects. - * - * @author Christian Tzolov - * @since 0.8.0 - */ -public final class ModelOptionsUtils { - - private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper() - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - - private final static List BEAN_MERGE_FIELD_EXCISIONS = List.of("class"); - - private static ConcurrentHashMap, List> REQUEST_FIELD_NAMES_PER_CLASS = new ConcurrentHashMap, List>(); - - private static AtomicReference SCHEMA_GENERATOR_CACHE = new AtomicReference<>(); - - private ModelOptionsUtils() { - - } - - /** - * Converts the given JSON string to a Map of String and Object. - * @param json the JSON string to convert to a Map. - * @return the converted Map. - */ - public static Map jsonToMap(String json) { - try { - return OBJECT_MAPPER.readValue(json, MAP_TYPE_REF); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static TypeReference> MAP_TYPE_REF = new TypeReference>() { - }; - - /** - * Converts the given JSON string to an Object of the given type. - * @param the type of the object to return. - * @param json the JSON string to convert to an object. - * @param type the type of the object to return. - * @return Object instance of the given type. - */ - public static T jsonToObject(String json, Class type) { - try { - return OBJECT_MAPPER.readValue(json, type); - } - catch (Exception e) { - throw new RuntimeException("Failed to json: " + json, e); - } - } - - /** - * Converts the given object to a JSON string. - * @param object the object to convert to a JSON string. - * @return the JSON string. - */ - public static String toJsonString(Object object) { - try { - return OBJECT_MAPPER.writeValueAsString(object); - } - catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - /** - * Merges the source object into the target object and returns an object represented - * by the given class. The JSON property names are used to match the fields to merge. - * The source non-null values override the target values with the same field name. The - * source null values are ignored. If the acceptedFieldNames is not empty, only the - * fields with the given names are merged and returned. If the acceptedFieldNames is - * empty, use the {@code @JsonProperty} names, inferred from the provided clazz. - * @param they type of the class to return. - * @param source the source object to merge. - * @param target the target object to merge into. - * @param clazz the class to return. - * @param acceptedFieldNames the list of field names accepted for the target object. - * @return the merged object represented by the given class. - */ - public static T merge(Object source, Object target, Class clazz, List acceptedFieldNames) { - - if (source == null) { - source = Map.of(); - } - - List requestFieldNames = CollectionUtils.isEmpty(acceptedFieldNames) - ? REQUEST_FIELD_NAMES_PER_CLASS.computeIfAbsent(clazz, ModelOptionsUtils::getJsonPropertyValues) - : acceptedFieldNames; - - if (CollectionUtils.isEmpty(requestFieldNames)) { - throw new IllegalArgumentException("No @JsonProperty fields found in the " + clazz.getName()); - } - - Map sourceMap = ModelOptionsUtils.objectToMap(source); - Map targetMap = ModelOptionsUtils.objectToMap(target); - - targetMap.putAll(sourceMap.entrySet() - .stream() - .filter(e -> e.getValue() != null) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()))); - - targetMap = targetMap.entrySet() - .stream() - .filter(e -> requestFieldNames.contains(e.getKey())) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - - return ModelOptionsUtils.mapToClass(targetMap, clazz); - } - - /** - * Merges the source object into the target object and returns an object represented - * by the given class. The JSON property names are used to match the fields to merge. - * The source non-null values override the target values with the same field name. The - * source null values are ignored. Returns the only field names that match the - * {@code @JsonProperty} names, inferred from the provided clazz. - * @param they type of the class to return. - * @param source the source object to merge. - * @param target the target object to merge into. - * @param clazz the class to return. - * @return the merged object represented by the given class. - */ - public static T merge(Object source, Object target, Class clazz) { - return ModelOptionsUtils.merge(source, target, clazz, null); - } - - /** - * Converts the given object to a Map. - * @param source the object to convert to a Map. - * @return the converted Map. - */ - public static Map objectToMap(Object source) { - if (source == null) { - return new HashMap<>(); - } - try { - String json = OBJECT_MAPPER.writeValueAsString(source); - return OBJECT_MAPPER.readValue(json, new TypeReference>() { - }) - .entrySet() - .stream() - .filter(e -> e.getValue() != null) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - } - catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - /** - * Converts the given Map to the given class. - * @param the type of the class to return. - * @param source the Map to convert to the given class. - * @param clazz the class to convert the Map to. - * @return the converted class. - */ - public static T mapToClass(Map source, Class clazz) { - try { - String json = OBJECT_MAPPER.writeValueAsString(source); - return OBJECT_MAPPER.readValue(json, clazz); - } - catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - /** - * Returns the list of name values of the {@link JsonProperty} annotations. - * @param clazz the class that contains fields annotated with {@link JsonProperty}. - * @return the list of values of the {@link JsonProperty} annotations. - */ - public static List getJsonPropertyValues(Class clazz) { - List values = new ArrayList<>(); - Field[] fields = clazz.getDeclaredFields(); - for (Field field : fields) { - JsonProperty jsonPropertyAnnotation = field.getAnnotation(JsonProperty.class); - if (jsonPropertyAnnotation != null) { - values.add(jsonPropertyAnnotation.value()); - } - } - return values; - } - - /** - * Returns a new instance of the targetBeanClazz that copies the bean values from the - * sourceBean instance. - * @param sourceBean the source bean to copy the values from. - * @param sourceInterfaceClazz the source interface class. Only the fields with the - * same name as the interface methods are copied. This allow the source object to be a - * subclass of the source interface with additional, non-interface fields. - * @param targetBeanClazz the target class, a subclass of the ChatOptions, to convert - * into. - * @param the target class type. - * @return a new instance of the targetBeanClazz with the values from the sourceBean - * instance. - */ - public static T copyToTarget(S sourceBean, Class sourceInterfaceClazz, - Class targetBeanClazz) { - - Assert.notNull(sourceInterfaceClazz, "SourceOptionsClazz must not be null"); - Assert.notNull(targetBeanClazz, "TargetOptionsClazz must not be null"); - - if (sourceBean == null) { - return null; - } - - if (sourceBean.getClass().isAssignableFrom(targetBeanClazz)) { - return (T) sourceBean; - } - - try { - T targetOptions = targetBeanClazz.getConstructor().newInstance(); - - ModelOptionsUtils.mergeBeans(sourceBean, targetOptions, sourceInterfaceClazz, true); - - return targetOptions; - } - catch (Exception e) { - throw new RuntimeException( - "Failed to convert the " + sourceInterfaceClazz.getName() + " into " + targetBeanClazz.getName(), - e); - } - } - - /** - * Merges the source object into the target object. The source null values are - * ignored. Only objects with Getter and Setter methods are supported. - * @param the type of the source and target object. - * @param source the source object to merge. - * @param target the target object to merge into. - * @param sourceInterfaceClazz the source interface class. Only the fields with the - * same name as the interface methods are merged. This allow the source object to be a - * subclass of the source interface with additional, non-interface fields. - * @param overrideNonNullTargetValues if true, the source non-null values override the - * target values with the same field name. If false, the source non-null values are - * ignored. - * @return the merged target object. - */ - public static T mergeBeans(S source, T target, Class sourceInterfaceClazz, - boolean overrideNonNullTargetValues) { - Assert.notNull(source, "Source object must not be null"); - Assert.notNull(target, "Target object must not be null"); - - BeanWrapper sourceBeanWrap = new BeanWrapperImpl(source); - BeanWrapper targetBeanWrap = new BeanWrapperImpl(target); - - List interfaceNames = Arrays.stream(sourceInterfaceClazz.getMethods()).map(m -> m.getName()).toList(); - - for (PropertyDescriptor descriptor : sourceBeanWrap.getPropertyDescriptors()) { - - if (!BEAN_MERGE_FIELD_EXCISIONS.contains(descriptor.getName()) - && interfaceNames.contains(toGetName(descriptor.getName()))) { - - String propertyName = descriptor.getName(); - Object value = sourceBeanWrap.getPropertyValue(propertyName); - - // Copy value to the target object - if (value != null) { - var targetValue = targetBeanWrap.getPropertyValue(propertyName); - - if (targetValue == null || overrideNonNullTargetValues) { - targetBeanWrap.setPropertyValue(propertyName, value); - } - } - } - } - - return target; - } - - private static String toGetName(String name) { - return "get" + name.substring(0, 1).toUpperCase() + name.substring(1); - } - - /** - * Generates JSON Schema (version 2020_12) for the given class. - * @param clazz the class to generate JSON Schema for. - * @param toUpperCaseTypeValues if true, the type values are converted to upper case. - * @return the generated JSON Schema as a String. - */ - public static String getJsonSchema(Class clazz, boolean toUpperCaseTypeValues) { - - if (SCHEMA_GENERATOR_CACHE.get() == null) { - - JacksonModule jacksonModule = new JacksonModule(JacksonOption.RESPECT_JSONPROPERTY_REQUIRED); - Swagger2Module swaggerModule = new Swagger2Module(); - - SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, - OptionPreset.PLAIN_JSON) - .with(Option.EXTRA_OPEN_API_FORMAT_VALUES) - .with(Option.PLAIN_DEFINITION_KEYS) - .with(swaggerModule) - .with(jacksonModule); - - SchemaGeneratorConfig config = configBuilder.build(); - SchemaGenerator generator = new SchemaGenerator(config); - SCHEMA_GENERATOR_CACHE.compareAndSet(null, generator); - } - - ObjectNode node = SCHEMA_GENERATOR_CACHE.get().generateSchema(clazz); - if (toUpperCaseTypeValues) { // Required for OpenAPI 3.0 (at least Vertex AI - // version of it). - toUpperCaseTypeValues(node); - } - - return node.toPrettyString(); - } - - public static void toUpperCaseTypeValues(ObjectNode node) { - if (node == null) { - return; - } - if (node.isObject()) { - node.fields().forEachRemaining(entry -> { - JsonNode value = entry.getValue(); - if (value.isObject()) { - toUpperCaseTypeValues((ObjectNode) value); - } - else if (value.isArray()) { - ((ArrayNode) value).elements().forEachRemaining(element -> { - if (element.isObject() || element.isArray()) { - toUpperCaseTypeValues((ObjectNode) element); - } - }); - } - else if (value.isTextual() && entry.getKey().equals("type")) { - String oldValue = ((ObjectNode) node).get("type").asText(); - ((ObjectNode) node).put("type", oldValue.toUpperCase()); - } - }); - } - else if (node.isArray()) { - node.elements().forEachRemaining(element -> { - if (element.isObject() || element.isArray()) { - toUpperCaseTypeValues((ObjectNode) element); - } - }); - } - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelRequest.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelRequest.java deleted file mode 100644 index b3c4969d4..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * 表示对AI模型的请求的接口。此接口封装了 与人工智能模型交互所需的必要信息,包括指令或 输入(通用类型T)和附加模型选项。它提供了一种标准化的方式 - * 向人工智能模型发送请求,确保包括所有必要的细节,并且可以易于管理。 - * - * Interface representing a request to an AI model. This interface encapsulates the - * necessary information required to interact with an AI model, including instructions or - * inputs (of generic type T) and additional model options. It provides a standardized way - * to send requests to AI models, ensuring that all necessary details are included and can - * be easily managed. - * - * @param the type of instructions or input required by the AI model - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ModelRequest { - - /** - * 检索AI模型所需的指令或输入。 返回AI模型所需的指令或输入 - * - * Retrieves the instructions or input required by the AI model. - * @return the instructions or input required by the AI model - */ - T getInstructions(); // required input - - /** - * 检索人工智能模型交互的可自定义选项。 返回AI模型交互的自定义选项 - * - * Retrieves the customizable options for AI model interactions. - * @return the customizable options for AI model interactions - */ - ModelOptions getOptions(); - -} \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResponse.java deleted file mode 100644 index b3f40ffe7..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResponse.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -import java.util.List; - -/** - * - * 表示从AI模型接收到的响应的接口。此接口提供 访问AI模型生成的主要结果或结果列表的方法,以及 以及响应元数据。它是封装和管理的标准化方式 - * 人工智能模型的输出,确保轻松检索和处理生成的信息 - * - * Interface representing the response received from an AI model. This interface provides - * methods to access the main result or a list of results generated by the AI model, along - * with the response metadata. It serves as a standardized way to encapsulate and manage - * the output from AI models, ensuring easy retrieval and processing of the generated - * information. - * - * @param the type of the result(s) provided by the AI model - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ModelResponse> { - - /** - * 检索AI模型的结果。 - * - * Retrieves the result of the AI model. - * @return the result generated by the AI model - */ - T getResult(); - - /** - * 检索AI模型生成的输出列表。 - * - * Retrieves the list of generated outputs by the AI model. - * @return the list of generated outputs - */ - List getResults(); - - /** - * 检索与AI模型的响应相关联的响应元数据。 - * - * Retrieves the response metadata associated with the AI model's response. - * @return the response metadata - */ - ResponseMetadata getMetadata(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResult.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResult.java deleted file mode 100644 index 5a5613a72..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ModelResult.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * This interface provides methods to access the main output of the AI model and the - * metadata associated with this result. It is designed to offer a standardized and - * comprehensive way to handle and interpret the outputs generated by AI models, catering - * to diverse AI applications and use cases. - * - * @param the type of the output generated by the AI model - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ModelResult { - - /** - * Retrieves the output generated by the AI model. - * @return the output generated by the AI model - */ - T getOutput(); - - /** - * Retrieves the metadata associated with the result of an AI model. - * @return the metadata associated with the result - */ - ResultMetadata getMetadata(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResponseMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResponseMetadata.java deleted file mode 100644 index 15e685d02..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResponseMetadata.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * 表示与AI模型的响应相关联的元数据的接口。此接口 旨在提供有关人工智能生成反应的附加信息 模型,包括处理细节和模型特定数据。它是一种价值 - * 核心领域内的对象,增强对人工智能模型的理解和管理 在各种应用中的响应。 - * - * Interface representing metadata associated with an AI model's response. This interface - * is designed to provide additional information about the generative response from an AI - * model, including processing details and model-specific data. It serves as a value - * object within the core domain, enhancing the understanding and management of AI model - * responses in various applications. - * - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ResponseMetadata { - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResultMetadata.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResultMetadata.java deleted file mode 100644 index 78d5f7f6a..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/ResultMetadata.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -/** - * Interface representing metadata associated with the results of an AI model. This - * interface focuses on providing additional context and insights into the results - * generated by AI models. It could include information like computation time, model - * version, or other relevant details that enhance understanding and management of AI - * model outputs in various applications. - * - * @author Mark Pollack - * @since 0.8.0 - */ -public interface ResultMetadata { - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/StreamingModelClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/StreamingModelClient.java deleted file mode 100644 index da1db1504..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/StreamingModelClient.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model; - -import reactor.core.publisher.Flux; - -/** - * The StreamingModelClient interface provides a generic API for invoking a AI models with - * streaming response. It abstracts the process of sending requests and receiving a - * streaming responses. The interface uses Java generics to accommodate different types of - * requests and responses, enhancing flexibility and adaptability across different AI - * model implementations. - * - * @param the generic type of the request to the AI model - * @param the generic type of a single item in the streaming response from the - * AI model - * @author Christian Tzolov - * @since 0.8.0 - */ -public interface StreamingModelClient, TResChunk extends ModelResponse> { - - /** - * Executes a method call to the AI model. - * @param request the request object to be sent to the AI model - * @return the streaming response from the AI model - */ - Flux stream(TReq request); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java deleted file mode 100644 index 67a34b1b1..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallSupport.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -import org.springframework.util.CollectionUtils; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** - * @author Christian Tzolov - */ -public abstract class AbstractFunctionCallSupport { - - protected final static boolean IS_RUNTIME_CALL = true; - - /** - * 函数回调寄存器用于按名称解析函数回调。 - * - * The function callback register is used to resolve the function callbacks by name. - */ - protected final Map functionCallbackRegister = new ConcurrentHashMap<>(); - - /** - * 函数回调上下文用于按名称解析函数回调来自Spring上下文。 - * 它是可选的,通常与Spring一起使用自动配置。 - * - * The function callback context is used to resolve the function callbacks by name - * from the Spring context. It is optional and usually used with Spring - * auto-configuration. - */ - protected final FunctionCallbackContext functionCallbackContext; - - public AbstractFunctionCallSupport(FunctionCallbackContext functionCallbackContext) { - this.functionCallbackContext = functionCallbackContext; - } - - public Map getFunctionCallbackRegister() { - return this.functionCallbackRegister; - } - - protected Set handleFunctionCallbackConfigurations(FunctionCallingOptions options, boolean isRuntimeCall) { - - Set functionToCall = new HashSet<>(); - - if (options != null) { - if (!CollectionUtils.isEmpty(options.getFunctionCallbacks())) { - options.getFunctionCallbacks().stream().forEach(functionCallback -> { - - // Register the tool callback. - if (isRuntimeCall) { - this.functionCallbackRegister.put(functionCallback.getName(), functionCallback); - } - else { - this.functionCallbackRegister.putIfAbsent(functionCallback.getName(), functionCallback); - } - - // Automatically enable the function, usually from prompt callback. - if (isRuntimeCall) { - functionToCall.add(functionCallback.getName()); - } - }); - } - - // Add the explicitly enabled functions. - if (!CollectionUtils.isEmpty(options.getFunctions())) { - functionToCall.addAll(options.getFunctions()); - } - } - - return functionToCall; - } - - /** - * Resolve the function callbacks by name. Retrieve them from the registry or try to - * resolve them from the Application Context. - * @param functionNames Name of function callbacks to retrieve. - * @return list of resolved FunctionCallbacks. - */ - protected List resolveFunctionCallbacks(Set functionNames) { - - List retrievedFunctionCallbacks = new ArrayList<>(); - - for (String functionName : functionNames) { - if (!this.functionCallbackRegister.containsKey(functionName)) { - - if (this.functionCallbackContext != null) { - FunctionCallback functionCallback = this.functionCallbackContext.getFunctionCallback(functionName, - null); - if (functionCallback != null) { - this.functionCallbackRegister.put(functionName, functionCallback); - } - else { - throw new IllegalStateException( - "No function callback [" + functionName + "] fund in tht FunctionCallbackContext"); - } - } - else { - throw new IllegalStateException("No function callback found for name: " + functionName); - } - } - FunctionCallback functionCallback = this.functionCallbackRegister.get(functionName); - - retrievedFunctionCallbacks.add(functionCallback); - } - - return retrievedFunctionCallbacks; - } - - /// - protected Resp callWithFunctionSupport(Req request) { - Resp response = this.doChatCompletion(request); - return this.handleFunctionCallOrReturn(request, response); - } - - protected Resp handleFunctionCallOrReturn(Req request, Resp response) { - - if (!this.isToolFunctionCall(response)) { - return response; - } - - // The chat completion tool call requires the complete conversation - // history. Including the initial user message. - List conversationHistory = new ArrayList<>(); - - conversationHistory.addAll(this.doGetUserMessages(request)); - - Msg responseMessage = this.doGetToolResponseMessage(response); - - // Add the assistant response to the message conversation history. - conversationHistory.add(responseMessage); - - Req newRequest = this.doCreateToolResponseRequest(request, responseMessage, conversationHistory); - - return this.callWithFunctionSupport(newRequest); - } - - abstract protected Req doCreateToolResponseRequest(Req previousRequest, Msg responseMessage, - List conversationHistory); - - abstract protected List doGetUserMessages(Req request); - - abstract protected Msg doGetToolResponseMessage(Resp response); - - abstract protected Resp doChatCompletion(Req request); - - abstract protected boolean isToolFunctionCall(Resp response); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java deleted file mode 100644 index 801ea3c10..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.util.Assert; - -import java.util.function.Function; - -/** - * Abstract implementation of the {@link FunctionCallback} for interacting with the - * Model's function calling protocol and a {@link Function} wrapping the interaction with - * the 3rd party service/function. - * - * Implement the {@code O apply(I request) } method to implement the interaction with the - * 3rd party service/function. - * - * The {@link #responseConverter} function is responsible to convert the 3rd party - * function's output type into a string expected by the LLM model. - * - * @param the 3rd party service input type. - * @param the 3rd party service output type. - * @author Christian Tzolov - */ -abstract class AbstractFunctionCallback implements Function, FunctionCallback { - - private final String name; - - private final String description; - - private final Class inputType; - - private final String inputTypeSchema; - - private final ObjectMapper objectMapper; - - private final Function responseConverter; - - /** - * Constructs a new {@link AbstractFunctionCallback} with the given name, description, - * input type and default object mapper. - * @param name Function name. Should be unique within the ChatClient's function - * registry. - * @param description Function description. Used as a "system prompt" by the model to - * decide if the function should be called. - * @param inputTypeSchema Used to compute, the argument's Schema (such as JSON Schema - * or OpenAPI Schema)required by the Model's function calling protocol. - * @param inputType Used to compute, the argument's JSON schema required by the - * Model's function calling protocol. - * @param responseConverter Used to convert the function's output type to a string. - * @param objectMapper Used to convert the function's input and output types to and - * from JSON. - */ - protected AbstractFunctionCallback(String name, String description, String inputTypeSchema, Class inputType, - Function responseConverter, ObjectMapper objectMapper) { - Assert.notNull(name, "Name must not be null"); - Assert.notNull(description, "Description must not be null"); - Assert.notNull(inputType, "InputType must not be null"); - Assert.notNull(inputTypeSchema, "InputTypeSchema must not be null"); - Assert.notNull(responseConverter, "ResponseConverter must not be null"); - Assert.notNull(objectMapper, "ObjectMapper must not be null"); - this.name = name; - this.description = description; - this.inputType = inputType; - this.inputTypeSchema = inputTypeSchema; - this.responseConverter = responseConverter; - this.objectMapper = objectMapper; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getDescription() { - return this.description; - } - - @Override - public String getInputTypeSchema() { - return this.inputTypeSchema; - } - - @Override - public String call(String functionArguments) { - - // Convert the tool calls JSON arguments into a Java function request object. - I request = fromJson(functionArguments, inputType); - - // extend conversation with function response. - return this.andThen(this.responseConverter).apply(request); - } - - private T fromJson(String json, Class targetClass) { - try { - return this.objectMapper.readValue(json, targetClass); - } - catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + ((inputType == null) ? 0 : inputType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AbstractFunctionCallback other = (AbstractFunctionCallback) obj; - if (name == null) { - if (other.name != null) - return false; - } - else if (!name.equals(other.name)) - return false; - if (description == null) { - if (other.description != null) - return false; - } - else if (!description.equals(other.description)) - return false; - if (inputType == null) { - if (other.inputType != null) - return false; - } - else if (!inputType.equals(other.inputType)) - return false; - return true; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallback.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallback.java deleted file mode 100644 index 91fc3ba8a..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallback.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -/** - * - * 表示模型函数调用处理程序。实现已向注册对触发函数调用的提示进行建模和调用。 - * - * https://blog.csdn.net/weixin_37546425/article/details/136402740 - * - * https://www.163.com/dy/article/ICE2S20P05119NPR.html - * - * Represents a model function call handler. Implementations are registered with the - * Models and called on prompts that trigger the function call. - * - * @author Christian Tzolov - */ -public interface FunctionCallback { - - /** - * @return Returns the Function name. Unique within the model. - */ - public String getName(); - - /** - * @return Returns the function description. This description is used by the model do - * decide if the function should be called or not. - */ - public String getDescription(); - - /** - * @return Returns the JSON schema of the function input type. - */ - public String getInputTypeSchema(); - - /** - * Called when a model detects and triggers a function call. The model is responsible - * to pass the function arguments in the pre-configured JSON schema format. - * @param functionInput JSON string with the function arguments to be passed to the - * function. The arguments are defined as JSON schema usually registered with the the - * model. - * @return String containing the function call response. - */ - public String call(String functionInput); - -} \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java deleted file mode 100644 index 5524182bc..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackContext.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.model.function; - -import com.fasterxml.jackson.annotation.JsonClassDescription; -import org.springframework.beans.BeansException; -import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; -import org.springframework.cloud.function.context.config.FunctionContextUtils; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Description; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; - -import java.lang.reflect.Type; -import java.util.function.Function; - -/** - * A Spring {@link ApplicationContextAware} implementation that provides a way to retrieve - * a {@link Function} from the Spring context and wrap it into a {@link FunctionCallback}. - * - * The name of the function is determined by the bean name. - * - * The description of the function is determined by the following rules: - *

    - *
  • Provided as a default description
  • - *
  • Provided as a {@code @Description} annotation on the bean
  • - *
  • Provided as a {@code @JsonClassDescription} annotation on the input class
  • - *
- * - * @author Christian Tzolov - * @author Christopher Smith - */ -public class FunctionCallbackContext implements ApplicationContextAware { - - private GenericApplicationContext applicationContext; - - private FunctionCallbackWrapper.Builder.SchemaType schemaType = FunctionCallbackWrapper.Builder.SchemaType.JSON_SCHEMA; - - public void setSchemaType(FunctionCallbackWrapper.Builder.SchemaType schemaType) { - this.schemaType = schemaType; - } - - @Override - public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { - this.applicationContext = (GenericApplicationContext) applicationContext; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public FunctionCallback getFunctionCallback(@NonNull String beanName, @Nullable String defaultDescription) { - - Type beanType = FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), beanName); - - if (beanType == null) { - throw new IllegalArgumentException( - "Functional bean with name: " + beanName + " does not exist in the context."); - } - - if (!Function.class.isAssignableFrom(FunctionTypeUtils.getRawType(beanType))) { - throw new IllegalArgumentException( - "Function call Bean must be of type Function. Found: " + beanType.getTypeName()); - } - - Type functionInputType = TypeResolverHelper.getFunctionArgumentType(beanType, 0); - - Class functionInputClass = FunctionTypeUtils.getRawType(functionInputType); - String functionName = beanName; - String functionDescription = defaultDescription; - - if (!StringUtils.hasText(functionDescription)) { - // Look for a Description annotation on the bean - Description descriptionAnnotation = applicationContext.findAnnotationOnBean(beanName, Description.class); - - if (descriptionAnnotation != null) { - functionDescription = descriptionAnnotation.value(); - } - - if (!StringUtils.hasText(functionDescription)) { - // Look for a JsonClassDescription annotation on the input class - JsonClassDescription jsonClassDescriptionAnnotation = functionInputClass - .getAnnotation(JsonClassDescription.class); - if (jsonClassDescriptionAnnotation != null) { - functionDescription = jsonClassDescriptionAnnotation.value(); - } - } - - if (!StringUtils.hasText(functionDescription)) { - throw new IllegalStateException("Could not determine function description." - + "Please provide a description either as a default parameter, via @Description annotation on the bean " - + "or @JsonClassDescription annotation on the input class."); - } - } - - Object bean = this.applicationContext.getBean(beanName); - - // TODO: 2024/3/16 fansili 适配jdk8 - return null; -// if (bean instanceof Function function) { -// return FunctionCallbackWrapper.builder(function) -// .withName(functionName) -// .withSchemaType(this.schemaType) -// .withDescription(functionDescription) -// .withInputType(functionInputClass) -// .build(); -// } -// else { -// throw new IllegalArgumentException("Bean must be of type Function"); -// } - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java deleted file mode 100644 index 23c981b0e..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallbackWrapper.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.springframework.ai.model.function; - -import org.springframework.ai.model.ModelOptionsUtils; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.util.Assert; - -import java.util.function.Function; - -/** - * Note that the underlying function is responsible for converting the output into format - * that can be consumed by the Model. The default implementation converts the output into - * String before sending it to the Model. Provide a custom function responseConverter - * implementation to override this. - * - */ -public class FunctionCallbackWrapper extends AbstractFunctionCallback { - - private final Function function; - - private FunctionCallbackWrapper(String name, String description, String inputTypeSchema, Class inputType, - Function responseConverter, Function function) { - super(name, description, inputTypeSchema, inputType, responseConverter, - new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); - Assert.notNull(function, "Function must not be null"); - this.function = function; - } - - @SuppressWarnings("unchecked") - private static Class resolveInputType(Function function) { - return (Class) TypeResolverHelper.getFunctionInputClass((Class>) function.getClass()); - } - - @Override - public O apply(I input) { - return this.function.apply(input); - } - - public static Builder builder(Function function) { - return new Builder<>(function); - } - - public static class Builder { - - public enum SchemaType { - - JSON_SCHEMA, OPEN_API_SCHEMA - - } - - private String name; - - private String description; - - private Class inputType; - - private final Function function; - - private SchemaType schemaType = SchemaType.JSON_SCHEMA; - - public Builder(Function function) { - Assert.notNull(function, "Function must not be null"); - this.function = function; - } - - // By default the response is converted to a JSON string. - private Function responseConverter = (response) -> ModelOptionsUtils.toJsonString(response); - - private String inputTypeSchema; - - private ObjectMapper objectMapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - public Builder withName(String name) { - Assert.hasText(name, "Name must not be empty"); - this.name = name; - return this; - } - - public Builder withDescription(String description) { - Assert.hasText(description, "Description must not be empty"); - this.description = description; - return this; - } - - @SuppressWarnings("unchecked") - public Builder withInputType(Class inputType) { - this.inputType = (Class) inputType; - return this; - } - - public Builder withResponseConverter(Function responseConverter) { - Assert.notNull(responseConverter, "ResponseConverter must not be null"); - this.responseConverter = responseConverter; - return this; - } - - public Builder withInputTypeSchema(String inputTypeSchema) { - Assert.hasText(inputTypeSchema, "InputTypeSchema must not be empty"); - this.inputTypeSchema = inputTypeSchema; - return this; - } - - public Builder withObjectMapper(ObjectMapper objectMapper) { - Assert.notNull(objectMapper, "ObjectMapper must not be null"); - this.objectMapper = objectMapper; - return this; - } - - public Builder withSchemaType(SchemaType schemaType) { - Assert.notNull(schemaType, "SchemaType must not be null"); - this.schemaType = schemaType; - return this; - } - - public FunctionCallbackWrapper build() { - - Assert.hasText(this.name, "Name must not be empty"); - Assert.hasText(this.description, "Description must not be empty"); - // Assert.notNull(this.inputType, "InputType must not be null"); - Assert.notNull(this.function, "Function must not be null"); - Assert.notNull(this.responseConverter, "ResponseConverter must not be null"); - Assert.notNull(this.objectMapper, "ObjectMapper must not be null"); - - if (this.inputType == null) { - this.inputType = resolveInputType(this.function); - } - - if (this.inputTypeSchema == null) { - boolean upperCaseTypeValues = this.schemaType == SchemaType.OPEN_API_SCHEMA; - this.inputTypeSchema = ModelOptionsUtils.getJsonSchema(this.inputType, upperCaseTypeValues); - } - - return new FunctionCallbackWrapper<>(this.name, this.description, this.inputTypeSchema, this.inputType, - this.responseConverter, this.function); - } - - } - -} \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java deleted file mode 100644 index c66a4f5b1..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -import java.util.List; -import java.util.Set; - -/** - * @author Christian Tzolov - */ -public interface FunctionCallingOptions { - - /** - * Function Callbacks to be registered with the ChatClient. For Prompt Options the - * functionCallbacks are automatically enabled for the duration of the prompt - * execution. For Default Options the FunctionCallbacks are registered but disabled by - * default. You have to use "functions" property to list the function names from the - * ChatClient registry to be used in the chat completion requests. - * @return Return the Function Callbacks to be registered with the ChatClient. - */ - List getFunctionCallbacks(); - - /** - * Set the Function Callbacks to be registered with the ChatClient. - * @param functionCallbacks the Function Callbacks to be registered with the - * ChatClient. - */ - void setFunctionCallbacks(List functionCallbacks); - - /** - * @return List of function names from the ChatClient registry to be used in the next - * chat completion requests. - */ - Set getFunctions(); - - /** - * Set the list of function names from the ChatClient registry to be used in the next - * chat completion requests. - * @param functions the list of function names from the ChatClient registry to be used - * in the next chat completion requests. - */ - void setFunctions(Set functions); - - /** - * @return Returns FunctionCallingOptionsBuilder to create a new instance of - * FunctionCallingOptions. - */ - public static FunctionCallingOptionsBuilder builder() { - return new FunctionCallingOptionsBuilder(); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java deleted file mode 100644 index 44044400d..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/FunctionCallingOptionsBuilder.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -import org.springframework.ai.chat.prompt.ChatOptions; -import org.springframework.util.Assert; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Builder for {@link FunctionCallingOptions}. Using the {@link FunctionCallingOptions} - * permits options portability between different AI providers that support - * function-calling. - * - * @author Christian Tzolov - * @since 0.8.1 - */ -public class FunctionCallingOptionsBuilder { - - private final PortableFunctionCallingOptions options; - - public FunctionCallingOptionsBuilder() { - this.options = new PortableFunctionCallingOptions(); - } - - public FunctionCallingOptionsBuilder withFunctionCallbacks(List functionCallbacks) { - this.options.setFunctionCallbacks(functionCallbacks); - return this; - } - - public FunctionCallingOptionsBuilder withFunctionCallback(FunctionCallback functionCallback) { - Assert.notNull(functionCallback, "FunctionCallback must not be null"); - this.options.getFunctionCallbacks().add(functionCallback); - return this; - } - - public FunctionCallingOptionsBuilder withFunctions(Set functions) { - this.options.setFunctions(functions); - return this; - } - - public FunctionCallingOptionsBuilder withFunction(String function) { - Assert.notNull(function, "Function must not be null"); - this.options.getFunctions().add(function); - return this; - } - - public FunctionCallingOptionsBuilder withTemperature(Float temperature) { - this.options.setTemperature(temperature); - return this; - } - - public FunctionCallingOptionsBuilder withTopP(Float topP) { - this.options.setTopP(topP); - return this; - } - - public FunctionCallingOptionsBuilder withTopK(Integer topK) { - this.options.setTopK(topK); - return this; - } - - public PortableFunctionCallingOptions build() { - return this.options; - } - - public static class PortableFunctionCallingOptions implements FunctionCallingOptions, ChatOptions { - - private List functionCallbacks = new ArrayList<>(); - - private Set functions = new HashSet<>(); - - private Float temperature; - - private Float topP; - - private Integer topK; - - @Override - public List getFunctionCallbacks() { - return this.functionCallbacks; - } - - @Override - public void setFunctionCallbacks(List functionCallbacks) { - Assert.notNull(functionCallbacks, "FunctionCallbacks must not be null"); - this.functionCallbacks = functionCallbacks; - } - - @Override - public Set getFunctions() { - return this.functions; - } - - @Override - public void setFunctions(Set functions) { - Assert.notNull(functions, "Functions must not be null"); - this.functions = functions; - } - - @Override - public Float getTemperature() { - return this.temperature; - } - - @Override - public void setTemperature(Float temperature) { - this.temperature = temperature; - } - - @Override - public Float getTopP() { - return this.topP; - } - - @Override - public void setTopP(Float topP) { - this.topP = topP; - } - - @Override - public Integer getTopK() { - return this.topK; - } - - @Override - public void setTopK(Integer topK) { - this.topK = topK; - } - - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java deleted file mode 100644 index 604ce0adc..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/function/TypeResolverHelper.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2024-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.model.function; - -import net.jodah.typetools.TypeResolver; - -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.function.Function; - -/** - * @author Christian Tzolov - */ -public class TypeResolverHelper { - - public static Class getFunctionInputClass(Class> functionClass) { - return getFunctionArgumentClass(functionClass, 0); - } - - public static Class getFunctionOutputClass(Class> functionClass) { - return getFunctionArgumentClass(functionClass, 1); - } - - public static Class getFunctionArgumentClass(Class> functionClass, int argumentIndex) { - Type type = TypeResolver.reify(Function.class, functionClass); - - var argumentType = type instanceof ParameterizedType - ? ((ParameterizedType) type).getActualTypeArguments()[argumentIndex] : Object.class; - - return toRawClass(argumentType); - } - - public static Type getFunctionInputType(Class> functionClass) { - return getFunctionArgumentType(functionClass, 0); - } - - public static Type getFunctionOutputType(Class> functionClass) { - return getFunctionArgumentType(functionClass, 1); - } - - public static Type getFunctionArgumentType(Class> functionClass, int argumentIndex) { - Type functionType = TypeResolver.reify(Function.class, functionClass); - return getFunctionArgumentType(functionType, argumentIndex); - } - - public static Type getFunctionArgumentType(Type functionType, int argumentIndex) { - var argumentType = functionType instanceof ParameterizedType - ? ((ParameterizedType) functionType).getActualTypeArguments()[argumentIndex] : Object.class; - - return argumentType; - } - - /** - * Effectively converts {@link Type} which could be {@link ParameterizedType} to raw - * Class (no generics). - * @param type actual {@link Type} instance - * @return instance of {@link Class} as raw representation of the provided - * {@link Type} - */ - public static Class toRawClass(Type type) { - return type != null - ? TypeResolver.resolveRawClass(type instanceof GenericArrayType ? type : TypeResolver.reify(type), null) - : null; - } - - // public static void main(String[] args) { - // Class> clazz = MockWeatherService.class; - // System.out.println(getFunctionInputType(clazz)); - - // } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/package-info.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/package-info.java deleted file mode 100644 index 12eaa53b4..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/model/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Provides a set of interfaces and classes for a generic API designed to interact with - * various AI models. This package includes interfaces for handling AI model calls, - * requests, responses, results, and associated metadata. It is designed to offer a - * flexible and adaptable framework for interacting with different types of AI models, - * abstracting the complexities involved in model invocation and result processing. The - * use of generics enhances the API's capability to work with a wide range of models, - * ensuring a broad applicability across diverse AI scenarios. - * - */ -package org.springframework.ai.model; \ No newline at end of file diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/midjourney/api/MidjourneyInteractionsApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/midjourney/api/MidjourneyInteractionsApi.java index 3771113d0..16d86a48f 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/midjourney/api/MidjourneyInteractionsApi.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/midjourney/api/MidjourneyInteractionsApi.java @@ -1,14 +1,14 @@ package org.springframework.ai.models.midjourney.api; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import org.springframework.ai.models.midjourney.MidjourneyConfig; import org.springframework.ai.models.midjourney.api.req.AttachmentsReq; import org.springframework.ai.models.midjourney.api.req.DescribeReq; import org.springframework.ai.models.midjourney.api.req.ReRollReq; import org.springframework.ai.models.midjourney.api.res.UploadAttachmentsRes; import org.springframework.ai.models.midjourney.util.MidjourneyUtil; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.FileSystemResource; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageApi.java deleted file mode 100644 index 6cde315e7..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageApi.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.springframework.ai.models.openai; - -import cn.hutool.json.JSONUtil; -import org.springframework.ai.models.openai.api.OpenAiImageRequest; -import org.springframework.ai.models.openai.api.OpenAiImageResponse; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import io.netty.channel.ChannelOption; -import lombok.extern.slf4j.Slf4j; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import org.springframework.http.client.reactive.ReactorClientHttpConnector; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.netty.http.client.HttpClient; - -import java.io.IOException; -import java.net.URI; -import java.time.Duration; - -/** - * open ai image - *

- * author: fansili - * time: 2024/3/17 09:53 - */ -@Slf4j -public class OpenAiImageApi { - - private static final String DEFAULT_BASE_URL = "https://api.openai.com"; - private String apiKey = "your-api-key"; - // 发送请求 webClient - private final WebClient webClient; - - private CloseableHttpClient httpclient = HttpClients.createDefault(); - - public OpenAiImageApi(String apiKey) { - this.apiKey = apiKey; - // 创建一个HttpClient实例并设置超时 - HttpClient httpClient = HttpClient.create() - .responseTimeout(Duration.ofSeconds(300)) // 设置响应超时时间为30秒 - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000 * 100); // 设置连接超时为5秒 - this.webClient = WebClient.builder() - .baseUrl(DEFAULT_BASE_URL) - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .build(); - } - - public OpenAiImageResponse createImage(OpenAiImageRequest request) { - HttpPost httpPost = new HttpPost(); - httpPost.setURI(URI.create(DEFAULT_BASE_URL.concat("/v1/images/generations"))); - httpPost.setHeader("Content-Type", "application/json"); - httpPost.setHeader("Authorization", "Bearer " + apiKey); - httpPost.setEntity(new StringEntity(JsonUtils.toJsonString(request), "UTF-8")); - - CloseableHttpResponse response= null; - try { - response = httpclient.execute(httpPost); - HttpEntity entity = response.getEntity(); - String resultJson = EntityUtils.toString(entity); - log.info("openai 图片生成结果: {}", resultJson); - return JSONUtil.toBean(resultJson, OpenAiImageResponse.class); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (response != null) { - try { - response.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } -// String res = webClient.post() -// .uri(uriBuilder -> uriBuilder.path("/v1/images/generations").build()) -// .header("Content-Type", "application/json") -// .header("Authorization", "Bearer " + apiKey) -// // 设置请求体(这里假设jsonStr是一个JSON格式的字符串) -// .body(BodyInserters.fromValue(JacksonUtil.toJson(request))) -// // 发送请求并获取响应体 -// .retrieve() -// // 转换响应体为String类型 -// .bodyToMono(String.class) -// .block(); - } -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageClient.java deleted file mode 100644 index 558a0e6e8..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageClient.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.springframework.ai.models.openai; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.codec.Base64; -import cn.hutool.core.util.StrUtil; -import cn.hutool.http.HttpUtil; -import org.springframework.ai.chat.ChatException; -import org.springframework.ai.models.yiyan.exception.YiYanApiException; -import cn.iocoder.yudao.framework.ai.core.exception.AiException; -import org.springframework.ai.models.openai.api.OpenAiImageRequest; -import org.springframework.ai.models.openai.api.OpenAiImageResponse; -import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; -import org.springframework.ai.image.*; -import org.springframework.retry.RetryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryListener; -import org.springframework.retry.support.RetryTemplate; - -import java.time.Duration; - -/** - * open ai 生成 image - * - * author: fansili - * time: 2024/3/17 09:51 - */ -@Slf4j -public class OpenAiImageClient implements ImageClient { - - /** - * open image ai - */ - private OpenAiImageApi openAiImageApi; - /** - * 默认使用的 ImageOptions - */ - private OpenAiImageOptions defaultImageOptions; - - - public final RetryTemplate retryTemplate = RetryTemplate.builder() - // 最大重试次数 10 - .maxAttempts(10) - .retryOn(YiYanApiException.class) - // 最大重试5次,第一次间隔3000ms,第二次3000ms * 2,第三次3000ms * 3,以此类推,最大间隔3 * 60000ms - .exponentialBackoff(Duration.ofMillis(3000), 2, Duration.ofMillis(3 * 60000)) - .withListener(new RetryListener() { - @Override - public void onError(RetryContext context, - RetryCallback callback, Throwable throwable) { - log.warn("重试异常:" + context.getRetryCount(), throwable); - }; - }) - .build(); - - public OpenAiImageClient(OpenAiImageApi openAiImageApi, OpenAiImageOptions defaultImageOptions) { - this.openAiImageApi = openAiImageApi; - this.defaultImageOptions = defaultImageOptions; - } - - @Override - public ImageResponse call(ImagePrompt imagePrompt) { - return this.retryTemplate.execute(ctx -> { - OpenAiImageOptions openAiImageOptions = getOpenAiImageOptions(imagePrompt); - // 创建请求 - OpenAiImageRequest request = new OpenAiImageRequest(); - BeanUtil.copyProperties(openAiImageOptions, request); - request.setPrompt(imagePrompt.getInstructions().get(0).getText()); - request.setModel(openAiImageOptions.getModel()); - request.setStyle(openAiImageOptions.getStyle().getStyle()); - request.setSize(openAiImageOptions.getSize()); - // 发送请求 - OpenAiImageResponse response = openAiImageApi.createImage(request); - if (response.getError() != null && !StrUtil.isBlank(response.getError().getMessage())) { - // code 错误没有编码,就先根据 message 来进行判断 - throw new AiException("openAi 图片生成失败! " + response.getError().getMessage()); - } - return new ImageResponse(response.getData().stream().map(res -> { - byte[] bytes = HttpUtil.downloadBytes(res.getUrl()); - String base64 = Base64.encode(bytes); - return new ImageGeneration(new Image(res.getUrl(), base64)); - }).toList()); - }); - } - - private @NotNull OpenAiImageOptions getOpenAiImageOptions(ImagePrompt imagePrompt) { - // 检查是否配置了 OpenAiImageOptions - if (defaultImageOptions == null && imagePrompt.getOptions() == null) { - throw new ChatException("OpenAiImageOptions 未配置参数!"); - } - // 优先使用 request 中的 ImageOptions - ImageOptions useImageOptions = imagePrompt.getOptions() == null ? defaultImageOptions : imagePrompt.getOptions(); - if (!(useImageOptions instanceof OpenAiImageOptions)) { - throw new ChatException("配置信息不正确,传入的必须是 OpenAiImageOptions!"); - } - // 转换 OpenAiImageOptions - OpenAiImageOptions openAiImageOptions = (OpenAiImageOptions) useImageOptions; - return openAiImageOptions; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageOptions.java deleted file mode 100644 index c6c903031..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/OpenAiImageOptions.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.springframework.ai.models.openai; - -import org.springframework.ai.image.ImageOptions; -import org.springframework.ai.models.openai.enums.OpenAiImageModelEnum; -import org.springframework.ai.models.openai.enums.OpenAiImageStyleEnum; -import lombok.Data; -import lombok.Getter; -import lombok.experimental.Accessors; - -/** - * open ai 配置文件 - * - * 文档地址:https://platform.openai.com/docs/api-reference/images/create - * - * author: fansili - * time: 2024/3/17 09:53 - */ -@Data -@Accessors(chain = true) -public class OpenAiImageOptions implements ImageOptions { - - // 必填字段,用于描述期望生成图像的文字说明。对于dall-e-2模型最大长度为1000个字符,对于dall-e-3模型最大长度为4000个字符。 - private String prompt; - - // 可选字段,默认为dall-e-2 - // 指定用于生成图像的模型名称。 - private OpenAiImageModelEnum model = OpenAiImageModelEnum.DALL_E_2; - - // 可选字段,默认为1 - // 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。 - private Integer n = 1; - - // 可选字段,默认为standard - // 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。 - private String quality = "standard"; - - // 可选字段,默认为url - // 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。 - private String responseFormat = "url"; - - // 可选字段,默认为1024x1024 - // 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。 - private String size = "1024x1024"; - - // 可选字段,默认为vivid - // 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。 - private OpenAiImageStyleEnum style = OpenAiImageStyleEnum.VIVID; - - // 可选字段 - // 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。 - private String endUserId = "UID123456"; - - @Getter - public enum ResponseFormatEnum { - - URL("url"), - BASE64("b64_json"), - - ; - - ResponseFormatEnum(String value) { - this.value = value; - } - - private String value; - } - - // - // 适配 spring ai - - @Override - public Integer getN() { - return this.n; - } - - @Override - public String getModel() { - return this.model.getModel(); - } - - @Override - public Integer getWidth() { - return null; - } - - @Override - public Integer getHeight() { - return null; - } - - @Override - public String getResponseFormat() { - return this.responseFormat; - } -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageRequest.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageRequest.java deleted file mode 100644 index 0c01e1ea0..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageRequest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.springframework.ai.models.openai.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; -import lombok.experimental.Accessors; - -/** - * open ai 配置文件 - * - * 文档地址:https://platform.openai.com/docs/api-reference/images/create - * - * author: fansili - * time: 2024/3/17 09:53 - */ -@Data -@Accessors(chain = true) -public class OpenAiImageRequest { - - // 必填字段,用于描述期望生成图像的文字说明。对于dall-e-2模型最大长度为1000个字符,对于dall-e-3模型最大长度为4000个字符。 - @JsonProperty("prompt") - private String prompt; - - // 可选字段,默认为dall-e-2、dall-e-3 - // 指定用于生成图像的模型名称。 - @JsonProperty("model") - private String model = "dall-e-2"; - - // 可选字段,默认为1 - // 生成图像的数量,必须在1到10之间。对于dall-e-3模型,目前仅支持n=1。 - @JsonProperty("n") - private Integer n = 1; - - // 可选字段,默认为standard - // 设置生成图像的质量。hd质量将创建细节更丰富、图像整体一致性更高的图片。该参数仅对dall-e-3模型有效。 - @JsonProperty("quality") - private String quality = "standard"; - - // 可选字段,默认为url - // 返回生成图像的格式。必须是url或b64_json中的一种。URL链接的有效期是从生成图像后开始计算的60分钟内有效。 - @JsonProperty("response_format") - private String responseFormat = "url"; - - // 可选字段,默认为1024x1024 - // 生成图像的尺寸大小。对于dall-e-2模型,尺寸可为256x256, 512x512, 或 1024x1024。对于dall-e-3模型,尺寸可为1024x1024, 1792x1024, 或 1024x1792。 - @JsonProperty("size") - private String size = "1024x1024"; - - // 可选字段,默认为vivid - // 图像生成的风格。可为vivid(生动)或natural(自然)。vivid会使模型偏向生成超现实和戏剧性的图像,而natural则会让模型产出更自然、不那么超现实的图像。该参数仅对dall-e-3模型有效。 - @JsonProperty("style") - private String style = "vivid"; - - // 可选字段 - // 代表您的终端用户的唯一标识符,有助于OpenAI监控并检测滥用行为。了解更多信息请参考官方文档。 - @JsonProperty("user") - private String endUserId = "UID123123"; - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageResponse.java deleted file mode 100644 index beab4cdee..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/openai/api/OpenAiImageResponse.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.ai.models.openai.api; - -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.List; - -/** - * image 返回 - * - * author: fansili - * time: 2024/3/17 10:27 - */ -@Data -@Accessors(chain = true) -public class OpenAiImageResponse { - - private long created; - private List data; - private Error error; - - @Data - @Accessors(chain = true) - public static class Item { - - private String url; - private String b64_json; - - } - - @Data - @Accessors(chain = true) - public static class Error { - private String code; - private String message; - private String param; - private String type; - } -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenChatClient.java index c1d0d41bf..f038bc83e 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenChatClient.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenChatClient.java @@ -1,5 +1,6 @@ package org.springframework.ai.models.tongyi; +import cn.iocoder.yudao.framework.ai.core.exception.ChatException; import org.springframework.ai.chat.*; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenOptions.java index 9a677607d..39db36608 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenOptions.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/tongyi/QianWenOptions.java @@ -41,25 +41,25 @@ public class QianWenOptions implements ChatOptions { return null; } - @Override - public void setTemperature(Float temperature) { - - } - - @Override - public void setTopP(Float topP) { - this.topP = topP; - } +// @Override +// public void setTemperature(Float temperature) { +// +// } +// +// @Override +// public void setTopP(Float topP) { +// this.topP = topP; +// } @Override public Integer getTopK() { return null; } - @Override - public void setTopK(Integer topK) { - - } +// @Override +// public void setTopK(Integer topK) { +// +// } @Data @Accessors diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoChatClient.java index 740d74910..0010a75fa 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoChatClient.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoChatClient.java @@ -2,6 +2,7 @@ package org.springframework.ai.models.xinghuo; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.exceptions.ExceptionUtil; +import cn.iocoder.yudao.framework.ai.core.exception.ChatException; import org.springframework.ai.chat.*; import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.chat.prompt.Prompt; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoOptions.java index 8efa7527b..bdc671092 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoOptions.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/xinghuo/XingHuoOptions.java @@ -49,28 +49,29 @@ public class XingHuoOptions implements ChatOptions { return this.temperature; } - @Override - public void setTemperature(Float temperature) { - this.temperature = temperature; - } +// @Override +// public void setTemperature(Float temperature) { +// this.temperature = temperature; +// } @Override public Float getTopP() { return null; } - @Override - public void setTopP(Float topP) { - - } +// @Override +// public void setTopP(Float topP) { +// +// } @Override public Integer getTopK() { return this.topK; } - @Override - public void setTopK(Integer topK) { - this.topK = topK; - } +// @Override +// public void setTopK(Integer topK) { +// this.topK = topK; +// } + } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanChatClient.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanChatClient.java index 5d1dd4f76..e0da409ec 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanChatClient.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanChatClient.java @@ -1,6 +1,7 @@ package org.springframework.ai.models.yiyan; import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.yudao.framework.ai.core.exception.ChatException; import org.springframework.ai.chat.*; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.MessageType; diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanOptions.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanOptions.java index aac8e4949..0cb1481b3 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanOptions.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/models/yiyan/YiYanOptions.java @@ -114,20 +114,20 @@ public class YiYanOptions implements ChatOptions { return this.temperature; } - @Override - public void setTemperature(Float temperature) { - this.temperature = temperature; - } +// @Override +// public void setTemperature(Float temperature) { +// this.temperature = temperature; +// } @Override public Float getTopP() { return topP; } - @Override - public void setTopP(Float topP) { - this.topP = topP; - } +// @Override +// public void setTopP(Float topP) { +// this.topP = topP; +// } // 百度么有 topK @@ -136,7 +136,7 @@ public class YiYanOptions implements ChatOptions { return null; } - @Override - public void setTopK(Integer topK) { - } +// @Override +// public void setTopK(Integer topK) { +// } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java deleted file mode 100644 index a06827f39..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractConversionServiceOutputParser.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -import org.springframework.core.convert.support.DefaultConversionService; - -/** - * Abstract {@link OutputParser} implementation that uses a pre-configured - * {@link DefaultConversionService} to convert the LLM output into the desired type - * format. - * - * @param Specifies the desired response type. - * @author Mark Pollack - * @author Christian Tzolov - */ -public abstract class AbstractConversionServiceOutputParser implements OutputParser { - - private final DefaultConversionService conversionService; - - public AbstractConversionServiceOutputParser(DefaultConversionService conversionService) { - this.conversionService = conversionService; - } - - public DefaultConversionService getConversionService() { - return conversionService; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java deleted file mode 100644 index 01dbadaf1..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/AbstractMessageConverterOutputParser.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -import org.springframework.messaging.converter.MessageConverter; - -/** - * Abstract {@link OutputParser} implementation that uses a pre-configured - * {@link MessageConverter} to convert the LLM output into the desired type format. - * - * @param Specifies the desired response type. - * @author Mark Pollack - * @author Christian Tzolov - */ -public abstract class AbstractMessageConverterOutputParser implements OutputParser { - - private MessageConverter messageConverter; - - public AbstractMessageConverterOutputParser(MessageConverter messageConverter) { - this.messageConverter = messageConverter; - } - - public MessageConverter getMessageConverter() { - return this.messageConverter; - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/BeanOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/BeanOutputParser.java deleted file mode 100644 index fa09c26af..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/BeanOutputParser.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.util.DefaultIndenter; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.github.victools.jsonschema.generator.SchemaGenerator; -import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; -import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; -import com.github.victools.jsonschema.module.jackson.JacksonModule; - -import java.util.Map; -import java.util.Objects; - -import static com.github.victools.jsonschema.generator.OptionPreset.PLAIN_JSON; -import static com.github.victools.jsonschema.generator.SchemaVersion.DRAFT_2020_12; - -/** - * An implementation of {@link OutputParser} that transforms the LLM output to a specific - * object type using JSON schema. This parser works by generating a JSON schema based on a - * given Java class, which is then used to validate and transform the LLM output into the - * desired type. - * - * @param The target type to which the output will be converted. - * @author Mark Pollack - * @author Christian Tzolov - * @author Sebastian Ullrich - * @author Kirk Lund - */ -public class BeanOutputParser implements OutputParser { - - /** Holds the generated JSON schema for the target type. */ - private String jsonSchema; - - /** The Java class representing the target type. */ - @SuppressWarnings({ "FieldMayBeFinal", "rawtypes" }) - private Class clazz; - - /** The object mapper used for deserialization and other JSON operations. */ - @SuppressWarnings("FieldMayBeFinal") - private ObjectMapper objectMapper; - - /** - * Constructor to initialize with the target type's class. - * @param clazz The target type's class. - */ - public BeanOutputParser(Class clazz) { - this(clazz, null); - } - - /** - * Constructor to initialize with the target type's class, a custom object mapper, and - * a line endings normalizer to ensure consistent line endings on any platform. - * @param clazz The target type's class. - * @param objectMapper Custom object mapper for JSON operations. endings. - */ - public BeanOutputParser(Class clazz, ObjectMapper objectMapper) { - Objects.requireNonNull(clazz, "Java Class cannot be null;"); - this.clazz = clazz; - this.objectMapper = objectMapper != null ? objectMapper : getObjectMapper(); - generateSchema(); - } - - /** - * Generates the JSON schema for the target type. - */ - private void generateSchema() { - JacksonModule jacksonModule = new JacksonModule(); - SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(DRAFT_2020_12, PLAIN_JSON) - .with(jacksonModule); - SchemaGeneratorConfig config = configBuilder.build(); - SchemaGenerator generator = new SchemaGenerator(config); - JsonNode jsonNode = generator.generateSchema(this.clazz); - ObjectWriter objectWriter = new ObjectMapper() - .writer(new DefaultPrettyPrinter().withObjectIndenter(new DefaultIndenter().withLinefeed("\n"))); - try { - this.jsonSchema = objectWriter.writeValueAsString(jsonNode); - } - catch (JsonProcessingException e) { - throw new RuntimeException("Could not pretty print json schema for " + this.clazz, e); - } - } - - @Override - /** - * Parses the given text to transform it to the desired target type. - * @param text The LLM output in string format. - * @return The parsed output in the desired target type. - */ - public T parse(String text) { - try { - // If the response is a JSON Schema, extract the properties and use them as - // the response. - text = this.jsonSchemaToInstance(text); - return (T) this.objectMapper.readValue(text, this.clazz); - } - catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - /** - * Converts a JSON Schema to an instance based on a given text. - * @param text The JSON Schema in string format. - * @return The JSON instance generated from the JSON Schema, or the original text if - * the input is not a JSON Schema. - */ - private String jsonSchemaToInstance(String text) { - try { - Map map = this.objectMapper.readValue(text, Map.class); - if (map.containsKey("$schema")) { - return this.objectMapper.writeValueAsString(map.get("properties")); - } - } - catch (Exception e) { - } - return text; - } - - /** - * Configures and returns an object mapper for JSON operations. - * @return Configured object mapper. - */ - protected ObjectMapper getObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper; - } - - /** - * Provides the expected format of the response, instructing that it should adhere to - * the generated JSON schema. - * @return The instruction format string. - */ - @Override - public String getFormat() { -// String template = """ -// Your response should be in JSON format. -// Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. -// Do not include markdown code blocks in your response. -// Here is the JSON Schema instance your output must adhere to: -// ```%s``` -// """; - String template = "Your response should be in JSON format.\n" + - "\t\t\t\tDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.\n" + - "\t\t\t\tDo not include markdown code blocks in your response.\n" + - "\t\t\t\tHere is the JSON Schema instance your output must adhere to:\n" + - "\t\t\t\t```%s```"; - return String.format(template, this.jsonSchema); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/FormatProvider.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/FormatProvider.java deleted file mode 100644 index 8d0cb76b0..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/FormatProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -/** - * Implementations of this interface provides instructions for how the output of a - * language generative should be formatted. - * - * @author Mark Pollack - */ -public interface FormatProvider { - - /** - * @return Returns a string containing instructions for how the output of a language - * generative should be formatted. - */ - String getFormat(); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/ListOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/ListOutputParser.java deleted file mode 100644 index d11225797..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/ListOutputParser.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.ai.parser; - -import org.springframework.core.convert.support.DefaultConversionService; - -import java.util.List; - -/** - * {@link OutputParser} implementation that uses a {@link DefaultConversionService} to - * convert the LLM output into a {@link List} instance. - * - * @author Mark Pollack - * @author Christian Tzolov - */ -public class ListOutputParser extends AbstractConversionServiceOutputParser> { - - public ListOutputParser(DefaultConversionService defaultConversionService) { - super(defaultConversionService); - } - - @Override - public String getFormat() { -// return """ -// Your response should be a list of comma separated values -// eg: `foo, bar, baz` -// """; - return "Your response should be a list of comma separated values\n" + - "\t\t\t\teg: `foo, bar, baz`"; - } - - @Override - public List parse(String text) { - return getConversionService().convert(text, List.class); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/MapOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/MapOutputParser.java deleted file mode 100644 index 90f017f79..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/MapOutputParser.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -import org.springframework.messaging.Message; -import org.springframework.messaging.converter.MappingJackson2MessageConverter; -import org.springframework.messaging.support.MessageBuilder; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - -/** - * {@link OutputParser} implementation that uses a pre-configured - * {@link MappingJackson2MessageConverter} to convert the LLM output into a - * java.util.Map<String, Object> instance. - * - * @author Mark Pollack - * @author Christian Tzolov - */ -public class MapOutputParser extends AbstractMessageConverterOutputParser> { - - public MapOutputParser() { - super(new MappingJackson2MessageConverter()); - } - - @Override - public Map parse(String text) { - Message message = MessageBuilder.withPayload(text.getBytes(StandardCharsets.UTF_8)).build(); - return (Map) getMessageConverter().fromMessage(message, HashMap.class); - } - - @Override - public String getFormat() { -// String raw = """ -// Your response should be in JSON format. -// The data structure for the JSON should match this Java class: %s -// Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. -// """; - String raw = "Your response should be in JSON format.\n" + - "\t\t\t\tThe data structure for the JSON should match this Java class: %s\n" + - "\t\t\t\tDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation."; - return String.format(raw, "java.util.HashMap"); - } - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/OutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/OutputParser.java deleted file mode 100644 index cbc7e6e5a..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/OutputParser.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -/** - * Converts the (raw) LLM output into a structured responses of type. The - * {@link FormatProvider#getFormat()} method should provide the LLM prompt description of - * the desired format. - * - * @param Specifies the desired response type. - * @author Mark Pollack - * @author Christian Tzolov - */ -public interface OutputParser extends Parser, FormatProvider { - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/Parser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/Parser.java deleted file mode 100644 index 559473f08..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/Parser.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ai.parser; - -@FunctionalInterface -public interface Parser { - - T parse(String text); - -} diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/README.md b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/README.md deleted file mode 100644 index 740e330f2..000000000 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/org/springframework/ai/parser/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Output Parsing - -* [Documentation](https://docs.spring.io/spring-ai/reference/concepts.html#_output_parsing) -* [Usage examples](https://github.com/spring-projects/spring-ai/blob/main/spring-ai-openai/src/test/java/org/springframework/ai/openai/client/ClientIT.java) - -The output of AI models traditionally arrives as a java.util.String, even if you ask for the reply to be in JSON. It may be the correct JSON, but it isn’t a JSON data structure. It is just a string. Also, asking "for JSON" as part of the prompt isn’t 100% accurate. - -This intricacy has led to the emergence of a specialized field involving the creation of prompts to yield the intended output, followed by parsing the resulting simple string into a usable data structure for application integration. - -Output parsing employs meticulously crafted prompts, often necessitating multiple interactions with the model to achieve the desired formatting. - -This challenge has prompted OpenAI to introduce 'OpenAI Functions' as a means to specify the desired output format from the model precisely. diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java index 0882f72a0..99e2b5f7a 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java @@ -37,8 +37,8 @@ public class QianWenChatClientTests { QianWenApi qianWenApi = new QianWenApi("sk-Zsd81gZYg7", QianWenChatModal.QWEN_72B_CHAT); QianWenOptions qianWenOptions = new QianWenOptions(); qianWenOptions.setTopP(0.8F); - qianWenOptions.setTopK(3); - qianWenOptions.setTemperature(0.6F); +// qianWenOptions.setTopK(3); TODO 芋艿:临时处理 +// qianWenOptions.setTemperature(0.6F); TODO 芋艿:临时处理 qianWenChatClient = new QianWenChatClient( qianWenApi, qianWenOptions diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openAiImage/OpenAiImageClientTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openAiImage/OpenAiImageClientTests.java index ba439c683..6944eed70 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openAiImage/OpenAiImageClientTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openAiImage/OpenAiImageClientTests.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.framework.ai.openAiImage; -import org.springframework.ai.models.openai.OpenAiImageApi; -import org.springframework.ai.models.openai.OpenAiImageClient; -import org.springframework.ai.models.openai.OpenAiImageOptions; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; import org.junit.Before; import org.junit.Test; +import org.springframework.ai.openai.OpenAiImageClient; +import org.springframework.ai.openai.OpenAiImageOptions; +import org.springframework.ai.openai.api.OpenAiImageApi; import javax.imageio.ImageIO; import javax.swing.*; @@ -29,8 +29,8 @@ public class OpenAiImageClientTests { public void setup() { // 初始化 openAiImageClient this.openAiImageClient = new OpenAiImageClient( - new OpenAiImageApi(""), - new OpenAiImageOptions().setResponseFormat(OpenAiImageOptions.ResponseFormatEnum.URL.getValue()) + new OpenAiImageApi("") +// new OpenAiImageOptions().setResponseFormat(OpenAiImageOptions.ResponseFormatEnum.URL.getValue()) TODO 芋艿:临时处理 ); }