Commit e889b8c1e0addb87d81c9d1f2f796899852c9813
1 parent
94e9ee95
适配jdk8(暂时编译没报错)
Showing
8 changed files
with
171 additions
and
146 deletions
yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml
| ... | ... | @@ -12,8 +12,8 @@ |
| 12 | 12 | <artifactId>yudao-spring-boot-starter-ai</artifactId> |
| 13 | 13 | |
| 14 | 14 | <properties> |
| 15 | - <maven.compiler.source>21</maven.compiler.source> | |
| 16 | - <maven.compiler.target>21</maven.compiler.target> | |
| 15 | + <maven.compiler.source>8</maven.compiler.source> | |
| 16 | + <maven.compiler.target>8</maven.compiler.target> | |
| 17 | 17 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| 18 | 18 | </properties> |
| 19 | 19 | <dependencies> | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/ChatResponse.java
| ... | ... | @@ -19,6 +19,8 @@ import cn.iocoder.yudao.framework.ai.chat.metadata.ChatResponseMetadata; |
| 19 | 19 | import cn.iocoder.yudao.framework.ai.model.ModelResponse; |
| 20 | 20 | import org.springframework.util.CollectionUtils; |
| 21 | 21 | |
| 22 | +import java.util.ArrayList; | |
| 23 | +import java.util.Collections; | |
| 22 | 24 | import java.util.List; |
| 23 | 25 | import java.util.Objects; |
| 24 | 26 | |
| ... | ... | @@ -54,7 +56,8 @@ public class ChatResponse implements ModelResponse<Generation> { |
| 54 | 56 | */ |
| 55 | 57 | public ChatResponse(List<Generation> generations, ChatResponseMetadata chatResponseMetadata) { |
| 56 | 58 | this.chatResponseMetadata = chatResponseMetadata; |
| 57 | - this.generations = List.copyOf(generations); | |
| 59 | +// this.generations = List.copyOf(generations); | |
| 60 | + this.generations = Collections.unmodifiableList(generations); | |
| 58 | 61 | } |
| 59 | 62 | |
| 60 | 63 | /** |
| ... | ... | @@ -98,8 +101,12 @@ public class ChatResponse implements ModelResponse<Generation> { |
| 98 | 101 | public boolean equals(Object o) { |
| 99 | 102 | if (this == o) |
| 100 | 103 | return true; |
| 101 | - if (!(o instanceof ChatResponse that)) | |
| 104 | +// if (!(o instanceof ChatResponse that)) | |
| 105 | +// return false; | |
| 106 | + if (!(o instanceof ChatResponse)) { | |
| 102 | 107 | return false; |
| 108 | + } | |
| 109 | + ChatResponse that = (ChatResponse) o; | |
| 103 | 110 | return Objects.equals(chatResponseMetadata, that.chatResponseMetadata) |
| 104 | 111 | && Objects.equals(generations, that.generations); |
| 105 | 112 | } | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/Generation.java
| ... | ... | @@ -63,8 +63,11 @@ public class Generation implements ModelResult<AssistantMessage> { |
| 63 | 63 | public boolean equals(Object o) { |
| 64 | 64 | if (this == o) |
| 65 | 65 | return true; |
| 66 | - if (!(o instanceof Generation that)) | |
| 66 | + | |
| 67 | + if (!(o instanceof Generation)) { | |
| 67 | 68 | return false; |
| 69 | + } | |
| 70 | + Generation that = (Generation) o; | |
| 68 | 71 | return Objects.equals(assistantMessage, that.assistantMessage) |
| 69 | 72 | && Objects.equals(chatGenerationMetadata, that.chatGenerationMetadata); |
| 70 | 73 | } | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/prompt/Prompt.java
| ... | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | |
| 17 | 17 | package cn.iocoder.yudao.framework.ai.chat.prompt; |
| 18 | 18 | |
| 19 | +import cn.iocoder.yudao.framework.ai.chat.ChatResponse; | |
| 19 | 20 | import cn.iocoder.yudao.framework.ai.chat.messages.Message; |
| 20 | 21 | import cn.iocoder.yudao.framework.ai.chat.messages.UserMessage; |
| 21 | 22 | import cn.iocoder.yudao.framework.ai.model.ModelOptions; |
| ... | ... | @@ -86,8 +87,12 @@ public class Prompt implements ModelRequest<List<Message>> { |
| 86 | 87 | public boolean equals(Object o) { |
| 87 | 88 | if (this == o) |
| 88 | 89 | return true; |
| 89 | - if (!(o instanceof Prompt prompt)) | |
| 90 | +// if (!(o instanceof Prompt prompt)) | |
| 91 | +// return false; | |
| 92 | + if (!(o instanceof Prompt)) { | |
| 90 | 93 | return false; |
| 94 | + } | |
| 95 | + Prompt prompt = (Prompt) o; | |
| 91 | 96 | return Objects.equals(this.messages, prompt.messages) && Objects.equals(this.modelOptions, prompt.modelOptions); |
| 92 | 97 | } |
| 93 | 98 | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/model/function/FunctionCallbackContext.java
| 1 | -/* | |
| 2 | - * Copyright 2024-2024 the original author or authors. | |
| 3 | - * | |
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | - * you may not use this file except in compliance with the License. | |
| 6 | - * You may obtain a copy of the License at | |
| 7 | - * | |
| 8 | - * https://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | - * | |
| 10 | - * Unless required by applicable law or agreed to in writing, software | |
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | - * See the License for the specific language governing permissions and | |
| 14 | - * limitations under the License. | |
| 15 | - */ | |
| 16 | -package cn.iocoder.yudao.framework.ai.model.function; | |
| 17 | - | |
| 18 | -import com.fasterxml.jackson.annotation.JsonClassDescription; | |
| 19 | -import org.springframework.beans.BeansException; | |
| 20 | -import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; | |
| 21 | -import org.springframework.cloud.function.context.config.FunctionContextUtils; | |
| 22 | -import org.springframework.context.ApplicationContext; | |
| 23 | -import org.springframework.context.ApplicationContextAware; | |
| 24 | -import org.springframework.context.annotation.Description; | |
| 25 | -import org.springframework.context.support.GenericApplicationContext; | |
| 26 | -import org.springframework.lang.NonNull; | |
| 27 | -import org.springframework.lang.Nullable; | |
| 28 | -import org.springframework.util.StringUtils; | |
| 29 | - | |
| 30 | -import java.lang.reflect.Type; | |
| 31 | -import java.util.function.Function; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * A Spring {@link ApplicationContextAware} implementation that provides a way to retrieve | |
| 35 | - * a {@link Function} from the Spring context and wrap it into a {@link FunctionCallback}. | |
| 36 | - * | |
| 37 | - * The name of the function is determined by the bean name. | |
| 38 | - * | |
| 39 | - * The description of the function is determined by the following rules: | |
| 40 | - * <ul> | |
| 41 | - * <li>Provided as a default description</li> | |
| 42 | - * <li>Provided as a {@code @Description} annotation on the bean</li> | |
| 43 | - * <li>Provided as a {@code @JsonClassDescription} annotation on the input class</li> | |
| 44 | - * </ul> | |
| 45 | - * | |
| 46 | - * @author Christian Tzolov | |
| 47 | - * @author Christopher Smith | |
| 48 | - */ | |
| 49 | -public class FunctionCallbackContext implements ApplicationContextAware { | |
| 50 | - | |
| 51 | - private GenericApplicationContext applicationContext; | |
| 52 | - | |
| 53 | - private FunctionCallbackWrapper.Builder.SchemaType schemaType = FunctionCallbackWrapper.Builder.SchemaType.JSON_SCHEMA; | |
| 54 | - | |
| 55 | - public void setSchemaType(FunctionCallbackWrapper.Builder.SchemaType schemaType) { | |
| 56 | - this.schemaType = schemaType; | |
| 57 | - } | |
| 58 | - | |
| 59 | - @Override | |
| 60 | - public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { | |
| 61 | - this.applicationContext = (GenericApplicationContext) applicationContext; | |
| 62 | - } | |
| 63 | - | |
| 64 | - @SuppressWarnings({ "rawtypes", "unchecked" }) | |
| 65 | - public FunctionCallback getFunctionCallback(@NonNull String beanName, @Nullable String defaultDescription) { | |
| 66 | - | |
| 67 | - Type beanType = FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), beanName); | |
| 68 | - | |
| 69 | - if (beanType == null) { | |
| 70 | - throw new IllegalArgumentException( | |
| 71 | - "Functional bean with name: " + beanName + " does not exist in the context."); | |
| 72 | - } | |
| 73 | - | |
| 74 | - if (!Function.class.isAssignableFrom(FunctionTypeUtils.getRawType(beanType))) { | |
| 75 | - throw new IllegalArgumentException( | |
| 76 | - "Function call Bean must be of type Function. Found: " + beanType.getTypeName()); | |
| 77 | - } | |
| 78 | - | |
| 79 | - Type functionInputType = TypeResolverHelper.getFunctionArgumentType(beanType, 0); | |
| 80 | - | |
| 81 | - Class<?> functionInputClass = FunctionTypeUtils.getRawType(functionInputType); | |
| 82 | - String functionName = beanName; | |
| 83 | - String functionDescription = defaultDescription; | |
| 84 | - | |
| 85 | - if (!StringUtils.hasText(functionDescription)) { | |
| 86 | - // Look for a Description annotation on the bean | |
| 87 | - Description descriptionAnnotation = applicationContext.findAnnotationOnBean(beanName, Description.class); | |
| 88 | - | |
| 89 | - if (descriptionAnnotation != null) { | |
| 90 | - functionDescription = descriptionAnnotation.value(); | |
| 91 | - } | |
| 92 | - | |
| 93 | - if (!StringUtils.hasText(functionDescription)) { | |
| 94 | - // Look for a JsonClassDescription annotation on the input class | |
| 95 | - JsonClassDescription jsonClassDescriptionAnnotation = functionInputClass | |
| 96 | - .getAnnotation(JsonClassDescription.class); | |
| 97 | - if (jsonClassDescriptionAnnotation != null) { | |
| 98 | - functionDescription = jsonClassDescriptionAnnotation.value(); | |
| 99 | - } | |
| 100 | - } | |
| 101 | - | |
| 102 | - if (!StringUtils.hasText(functionDescription)) { | |
| 103 | - throw new IllegalStateException("Could not determine function description." | |
| 104 | - + "Please provide a description either as a default parameter, via @Description annotation on the bean " | |
| 105 | - + "or @JsonClassDescription annotation on the input class."); | |
| 106 | - } | |
| 107 | - } | |
| 108 | - | |
| 109 | - Object bean = this.applicationContext.getBean(beanName); | |
| 110 | - | |
| 111 | - if (bean instanceof Function<?, ?> function) { | |
| 112 | - return FunctionCallbackWrapper.builder(function) | |
| 113 | - .withName(functionName) | |
| 114 | - .withSchemaType(this.schemaType) | |
| 115 | - .withDescription(functionDescription) | |
| 116 | - .withInputType(functionInputClass) | |
| 117 | - .build(); | |
| 118 | - } | |
| 119 | - else { | |
| 120 | - throw new IllegalArgumentException("Bean must be of type Function"); | |
| 121 | - } | |
| 122 | - } | |
| 123 | - | |
| 124 | -} | |
| 1 | +///* | |
| 2 | +// * Copyright 2024-2024 the original author or authors. | |
| 3 | +// * | |
| 4 | +// * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | +// * you may not use this file except in compliance with the License. | |
| 6 | +// * You may obtain a copy of the License at | |
| 7 | +// * | |
| 8 | +// * https://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | +// * | |
| 10 | +// * Unless required by applicable law or agreed to in writing, software | |
| 11 | +// * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | +// * See the License for the specific language governing permissions and | |
| 14 | +// * limitations under the License. | |
| 15 | +// */ | |
| 16 | +//package cn.iocoder.yudao.framework.ai.model.function; | |
| 17 | +// | |
| 18 | +//import com.fasterxml.jackson.annotation.JsonClassDescription; | |
| 19 | +//import org.springframework.beans.BeansException; | |
| 20 | +//import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; | |
| 21 | +//import org.springframework.cloud.function.context.config.FunctionContextUtils; | |
| 22 | +//import org.springframework.context.ApplicationContext; | |
| 23 | +//import org.springframework.context.ApplicationContextAware; | |
| 24 | +//import org.springframework.context.annotation.Description; | |
| 25 | +//import org.springframework.context.support.GenericApplicationContext; | |
| 26 | +//import org.springframework.lang.NonNull; | |
| 27 | +//import org.springframework.lang.Nullable; | |
| 28 | +//import org.springframework.util.StringUtils; | |
| 29 | +// | |
| 30 | +//import java.lang.reflect.Type; | |
| 31 | +//import java.util.function.Function; | |
| 32 | +// | |
| 33 | +///** | |
| 34 | +// * A Spring {@link ApplicationContextAware} implementation that provides a way to retrieve | |
| 35 | +// * a {@link Function} from the Spring context and wrap it into a {@link FunctionCallback}. | |
| 36 | +// * | |
| 37 | +// * The name of the function is determined by the bean name. | |
| 38 | +// * | |
| 39 | +// * The description of the function is determined by the following rules: | |
| 40 | +// * <ul> | |
| 41 | +// * <li>Provided as a default description</li> | |
| 42 | +// * <li>Provided as a {@code @Description} annotation on the bean</li> | |
| 43 | +// * <li>Provided as a {@code @JsonClassDescription} annotation on the input class</li> | |
| 44 | +// * </ul> | |
| 45 | +// * | |
| 46 | +// * @author Christian Tzolov | |
| 47 | +// * @author Christopher Smith | |
| 48 | +// */ | |
| 49 | +//public class FunctionCallbackContext implements ApplicationContextAware { | |
| 50 | +// | |
| 51 | +// private GenericApplicationContext applicationContext; | |
| 52 | +// | |
| 53 | +// private FunctionCallbackWrapper.Builder.SchemaType schemaType = FunctionCallbackWrapper.Builder.SchemaType.JSON_SCHEMA; | |
| 54 | +// | |
| 55 | +// public void setSchemaType(FunctionCallbackWrapper.Builder.SchemaType schemaType) { | |
| 56 | +// this.schemaType = schemaType; | |
| 57 | +// } | |
| 58 | +// | |
| 59 | +// @Override | |
| 60 | +// public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { | |
| 61 | +// this.applicationContext = (GenericApplicationContext) applicationContext; | |
| 62 | +// } | |
| 63 | +// | |
| 64 | +// @SuppressWarnings({ "rawtypes", "unchecked" }) | |
| 65 | +// public FunctionCallback getFunctionCallback(@NonNull String beanName, @Nullable String defaultDescription) { | |
| 66 | +// | |
| 67 | +// Type beanType = FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), beanName); | |
| 68 | +// | |
| 69 | +// if (beanType == null) { | |
| 70 | +// throw new IllegalArgumentException( | |
| 71 | +// "Functional bean with name: " + beanName + " does not exist in the context."); | |
| 72 | +// } | |
| 73 | +// | |
| 74 | +// if (!Function.class.isAssignableFrom(FunctionTypeUtils.getRawType(beanType))) { | |
| 75 | +// throw new IllegalArgumentException( | |
| 76 | +// "Function call Bean must be of type Function. Found: " + beanType.getTypeName()); | |
| 77 | +// } | |
| 78 | +// | |
| 79 | +// Type functionInputType = TypeResolverHelper.getFunctionArgumentType(beanType, 0); | |
| 80 | +// | |
| 81 | +// Class<?> functionInputClass = FunctionTypeUtils.getRawType(functionInputType); | |
| 82 | +// String functionName = beanName; | |
| 83 | +// String functionDescription = defaultDescription; | |
| 84 | +// | |
| 85 | +// if (!StringUtils.hasText(functionDescription)) { | |
| 86 | +// // Look for a Description annotation on the bean | |
| 87 | +// Description descriptionAnnotation = applicationContext.findAnnotationOnBean(beanName, Description.class); | |
| 88 | +// | |
| 89 | +// if (descriptionAnnotation != null) { | |
| 90 | +// functionDescription = descriptionAnnotation.value(); | |
| 91 | +// } | |
| 92 | +// | |
| 93 | +// if (!StringUtils.hasText(functionDescription)) { | |
| 94 | +// // Look for a JsonClassDescription annotation on the input class | |
| 95 | +// JsonClassDescription jsonClassDescriptionAnnotation = functionInputClass | |
| 96 | +// .getAnnotation(JsonClassDescription.class); | |
| 97 | +// if (jsonClassDescriptionAnnotation != null) { | |
| 98 | +// functionDescription = jsonClassDescriptionAnnotation.value(); | |
| 99 | +// } | |
| 100 | +// } | |
| 101 | +// | |
| 102 | +// if (!StringUtils.hasText(functionDescription)) { | |
| 103 | +// throw new IllegalStateException("Could not determine function description." | |
| 104 | +// + "Please provide a description either as a default parameter, via @Description annotation on the bean " | |
| 105 | +// + "or @JsonClassDescription annotation on the input class."); | |
| 106 | +// } | |
| 107 | +// } | |
| 108 | +// | |
| 109 | +// Object bean = this.applicationContext.getBean(beanName); | |
| 110 | +// | |
| 111 | +// if (bean instanceof Function<?, ?> function) { | |
| 112 | +// return FunctionCallbackWrapper.builder(function) | |
| 113 | +// .withName(functionName) | |
| 114 | +// .withSchemaType(this.schemaType) | |
| 115 | +// .withDescription(functionDescription) | |
| 116 | +// .withInputType(functionInputClass) | |
| 117 | +// .build(); | |
| 118 | +// } | |
| 119 | +// else { | |
| 120 | +// throw new IllegalArgumentException("Bean must be of type Function"); | |
| 121 | +// } | |
| 122 | +// } | |
| 123 | +// | |
| 124 | +//} | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/BeanOutputParser.java
| ... | ... | @@ -153,13 +153,18 @@ public class BeanOutputParser<T> implements OutputParser<T> { |
| 153 | 153 | */ |
| 154 | 154 | @Override |
| 155 | 155 | public String getFormat() { |
| 156 | - String template = """ | |
| 157 | - Your response should be in JSON format. | |
| 158 | - Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. | |
| 159 | - Do not include markdown code blocks in your response. | |
| 160 | - Here is the JSON Schema instance your output must adhere to: | |
| 161 | - ```%s``` | |
| 162 | - """; | |
| 156 | +// String template = """ | |
| 157 | +// Your response should be in JSON format. | |
| 158 | +// Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. | |
| 159 | +// Do not include markdown code blocks in your response. | |
| 160 | +// Here is the JSON Schema instance your output must adhere to: | |
| 161 | +// ```%s``` | |
| 162 | +// """; | |
| 163 | + String template = "Your response should be in JSON format.\n" + | |
| 164 | + "\t\t\t\tDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.\n" + | |
| 165 | + "\t\t\t\tDo not include markdown code blocks in your response.\n" + | |
| 166 | + "\t\t\t\tHere is the JSON Schema instance your output must adhere to:\n" + | |
| 167 | + "\t\t\t\t```%s```"; | |
| 163 | 168 | return String.format(template, this.jsonSchema); |
| 164 | 169 | } |
| 165 | 170 | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/ListOutputParser.java
| ... | ... | @@ -34,10 +34,12 @@ public class ListOutputParser extends AbstractConversionServiceOutputParser<List |
| 34 | 34 | |
| 35 | 35 | @Override |
| 36 | 36 | public String getFormat() { |
| 37 | - return """ | |
| 38 | - Your response should be a list of comma separated values | |
| 39 | - eg: `foo, bar, baz` | |
| 40 | - """; | |
| 37 | +// return """ | |
| 38 | +// Your response should be a list of comma separated values | |
| 39 | +// eg: `foo, bar, baz` | |
| 40 | +// """; | |
| 41 | + return "Your response should be a list of comma separated values\n" + | |
| 42 | + "\t\t\t\teg: `foo, bar, baz`"; | |
| 41 | 43 | } |
| 42 | 44 | |
| 43 | 45 | @Override | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/MapOutputParser.java
| ... | ... | @@ -46,11 +46,14 @@ public class MapOutputParser extends AbstractMessageConverterOutputParser<Map<St |
| 46 | 46 | |
| 47 | 47 | @Override |
| 48 | 48 | public String getFormat() { |
| 49 | - String raw = """ | |
| 50 | - Your response should be in JSON format. | |
| 51 | - The data structure for the JSON should match this Java class: %s | |
| 52 | - Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. | |
| 53 | - """; | |
| 49 | +// String raw = """ | |
| 50 | +// Your response should be in JSON format. | |
| 51 | +// The data structure for the JSON should match this Java class: %s | |
| 52 | +// Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. | |
| 53 | +// """; | |
| 54 | + String raw = "Your response should be in JSON format.\n" + | |
| 55 | + "\t\t\t\tThe data structure for the JSON should match this Java class: %s\n" + | |
| 56 | + "\t\t\t\tDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation."; | |
| 54 | 57 | return String.format(raw, "java.util.HashMap"); |
| 55 | 58 | } |
| 56 | 59 | ... | ... |