From e889b8c1e0addb87d81c9d1f2f796899852c9813 Mon Sep 17 00:00:00 2001 From: cherishsince Date: Sat, 16 Mar 2024 21:38:31 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8Djdk8(=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E6=B2=A1=E6=8A=A5=E9=94=99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao-spring-boot-starter-ai/pom.xml | 4 +- .../yudao/framework/ai/chat/ChatResponse.java | 11 +- .../yudao/framework/ai/chat/Generation.java | 5 +- .../framework/ai/chat/prompt/Prompt.java | 7 +- .../function/FunctionCallbackContext.java | 248 +++++++++--------- .../framework/ai/parser/BeanOutputParser.java | 19 +- .../framework/ai/parser/ListOutputParser.java | 10 +- .../framework/ai/parser/MapOutputParser.java | 13 +- 8 files changed, 171 insertions(+), 146 deletions(-) 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 276e87733..a90180516 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml @@ -12,8 +12,8 @@ yudao-spring-boot-starter-ai - 21 - 21 + 8 + 8 UTF-8 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/ChatResponse.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/ChatResponse.java index 1360336fb..a6de72d7a 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/ChatResponse.java +++ b/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; import cn.iocoder.yudao.framework.ai.model.ModelResponse; import org.springframework.util.CollectionUtils; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -54,7 +56,8 @@ public class ChatResponse implements ModelResponse { */ public ChatResponse(List generations, ChatResponseMetadata chatResponseMetadata) { this.chatResponseMetadata = chatResponseMetadata; - this.generations = List.copyOf(generations); +// this.generations = List.copyOf(generations); + this.generations = Collections.unmodifiableList(generations); } /** @@ -98,8 +101,12 @@ public class ChatResponse implements ModelResponse { public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof ChatResponse that)) +// 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); } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/Generation.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/Generation.java index e84ffd409..1835d16d2 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/Generation.java +++ b/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 { public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof Generation that)) + + if (!(o instanceof Generation)) { return false; + } + Generation that = (Generation) o; return Objects.equals(assistantMessage, that.assistantMessage) && Objects.equals(chatGenerationMetadata, that.chatGenerationMetadata); } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/prompt/Prompt.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/prompt/Prompt.java index f9eb37409..95b5cd8aa 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/prompt/Prompt.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/chat/prompt/Prompt.java @@ -16,6 +16,7 @@ package cn.iocoder.yudao.framework.ai.chat.prompt; +import cn.iocoder.yudao.framework.ai.chat.ChatResponse; import cn.iocoder.yudao.framework.ai.chat.messages.Message; import cn.iocoder.yudao.framework.ai.chat.messages.UserMessage; import cn.iocoder.yudao.framework.ai.model.ModelOptions; @@ -86,8 +87,12 @@ public class Prompt implements ModelRequest> { public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof Prompt prompt)) +// 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); } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/model/function/FunctionCallbackContext.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/model/function/FunctionCallbackContext.java index dd5b0ee7c..917882358 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/model/function/FunctionCallbackContext.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/model/function/FunctionCallbackContext.java @@ -1,124 +1,124 @@ -/* - * 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 cn.iocoder.yudao.framework.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); - - 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"); - } - } - -} +///* +// * 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 cn.iocoder.yudao.framework.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); +// +// 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/cn/iocoder/yudao/framework/ai/parser/BeanOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/BeanOutputParser.java index 4eb08ce29..109e75fc4 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/BeanOutputParser.java +++ b/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 implements OutputParser { */ @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. +// 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/cn/iocoder/yudao/framework/ai/parser/ListOutputParser.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/ListOutputParser.java index 1eb936eac..37fd49b89 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/parser/ListOutputParser.java +++ b/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