适配jdk8(暂时编译没报错)

This commit is contained in:
cherishsince 2024-03-16 21:38:31 +08:00
parent 94e9ee9590
commit e889b8c1e0
8 changed files with 171 additions and 146 deletions

View File

@ -12,8 +12,8 @@
<artifactId>yudao-spring-boot-starter-ai</artifactId> <artifactId>yudao-spring-boot-starter-ai</artifactId>
<properties> <properties>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencies> <dependencies>

View File

@ -19,6 +19,8 @@ import cn.iocoder.yudao.framework.ai.chat.metadata.ChatResponseMetadata;
import cn.iocoder.yudao.framework.ai.model.ModelResponse; import cn.iocoder.yudao.framework.ai.model.ModelResponse;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -54,7 +56,8 @@ public class ChatResponse implements ModelResponse<Generation> {
*/ */
public ChatResponse(List<Generation> generations, ChatResponseMetadata chatResponseMetadata) { public ChatResponse(List<Generation> generations, ChatResponseMetadata chatResponseMetadata) {
this.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<Generation> {
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) if (this == o)
return true; return true;
if (!(o instanceof ChatResponse that)) // if (!(o instanceof ChatResponse that))
// return false;
if (!(o instanceof ChatResponse)) {
return false; return false;
}
ChatResponse that = (ChatResponse) o;
return Objects.equals(chatResponseMetadata, that.chatResponseMetadata) return Objects.equals(chatResponseMetadata, that.chatResponseMetadata)
&& Objects.equals(generations, that.generations); && Objects.equals(generations, that.generations);
} }

View File

@ -63,8 +63,11 @@ public class Generation implements ModelResult<AssistantMessage> {
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) if (this == o)
return true; return true;
if (!(o instanceof Generation that))
if (!(o instanceof Generation)) {
return false; return false;
}
Generation that = (Generation) o;
return Objects.equals(assistantMessage, that.assistantMessage) return Objects.equals(assistantMessage, that.assistantMessage)
&& Objects.equals(chatGenerationMetadata, that.chatGenerationMetadata); && Objects.equals(chatGenerationMetadata, that.chatGenerationMetadata);
} }

View File

@ -16,6 +16,7 @@
package cn.iocoder.yudao.framework.ai.chat.prompt; 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.Message;
import cn.iocoder.yudao.framework.ai.chat.messages.UserMessage; import cn.iocoder.yudao.framework.ai.chat.messages.UserMessage;
import cn.iocoder.yudao.framework.ai.model.ModelOptions; import cn.iocoder.yudao.framework.ai.model.ModelOptions;
@ -86,8 +87,12 @@ public class Prompt implements ModelRequest<List<Message>> {
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) if (this == o)
return true; return true;
if (!(o instanceof Prompt prompt)) // if (!(o instanceof Prompt prompt))
// return false;
if (!(o instanceof Prompt)) {
return false; return false;
}
Prompt prompt = (Prompt) o;
return Objects.equals(this.messages, prompt.messages) && Objects.equals(this.modelOptions, prompt.modelOptions); return Objects.equals(this.messages, prompt.messages) && Objects.equals(this.modelOptions, prompt.modelOptions);
} }

View File

@ -1,124 +1,124 @@
/* ///*
* Copyright 2024-2024 the original author or authors. // * Copyright 2024-2024 the original author or authors.
* // *
* Licensed under the Apache License, Version 2.0 (the "License"); // * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. // * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at // * You may obtain a copy of the License at
* // *
* https://www.apache.org/licenses/LICENSE-2.0 // * https://www.apache.org/licenses/LICENSE-2.0
* // *
* Unless required by applicable law or agreed to in writing, software // * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, // * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and // * See the License for the specific language governing permissions and
* limitations under the License. // * limitations under the License.
*/ // */
package cn.iocoder.yudao.framework.ai.model.function; //package cn.iocoder.yudao.framework.ai.model.function;
//
import com.fasterxml.jackson.annotation.JsonClassDescription; //import com.fasterxml.jackson.annotation.JsonClassDescription;
import org.springframework.beans.BeansException; //import org.springframework.beans.BeansException;
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; //import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
import org.springframework.cloud.function.context.config.FunctionContextUtils; //import org.springframework.cloud.function.context.config.FunctionContextUtils;
import org.springframework.context.ApplicationContext; //import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; //import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Description; //import org.springframework.context.annotation.Description;
import org.springframework.context.support.GenericApplicationContext; //import org.springframework.context.support.GenericApplicationContext;
import org.springframework.lang.NonNull; //import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable; //import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; //import org.springframework.util.StringUtils;
//
import java.lang.reflect.Type; //import java.lang.reflect.Type;
import java.util.function.Function; //import java.util.function.Function;
//
/** ///**
* A Spring {@link ApplicationContextAware} implementation that provides a way to retrieve // * 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}. // * 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 name of the function is determined by the bean name.
* // *
* The description of the function is determined by the following rules: // * The description of the function is determined by the following rules:
* <ul> // * <ul>
* <li>Provided as a default description</li> // * <li>Provided as a default description</li>
* <li>Provided as a {@code @Description} annotation on the bean</li> // * <li>Provided as a {@code @Description} annotation on the bean</li>
* <li>Provided as a {@code @JsonClassDescription} annotation on the input class</li> // * <li>Provided as a {@code @JsonClassDescription} annotation on the input class</li>
* </ul> // * </ul>
* // *
* @author Christian Tzolov // * @author Christian Tzolov
* @author Christopher Smith // * @author Christopher Smith
*/ // */
public class FunctionCallbackContext implements ApplicationContextAware { //public class FunctionCallbackContext implements ApplicationContextAware {
//
private GenericApplicationContext applicationContext; // private GenericApplicationContext applicationContext;
//
private FunctionCallbackWrapper.Builder.SchemaType schemaType = FunctionCallbackWrapper.Builder.SchemaType.JSON_SCHEMA; // private FunctionCallbackWrapper.Builder.SchemaType schemaType = FunctionCallbackWrapper.Builder.SchemaType.JSON_SCHEMA;
//
public void setSchemaType(FunctionCallbackWrapper.Builder.SchemaType schemaType) { // public void setSchemaType(FunctionCallbackWrapper.Builder.SchemaType schemaType) {
this.schemaType = schemaType; // this.schemaType = schemaType;
} // }
//
@Override // @Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { // public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (GenericApplicationContext) applicationContext; // this.applicationContext = (GenericApplicationContext) applicationContext;
} // }
//
@SuppressWarnings({ "rawtypes", "unchecked" }) // @SuppressWarnings({ "rawtypes", "unchecked" })
public FunctionCallback getFunctionCallback(@NonNull String beanName, @Nullable String defaultDescription) { // public FunctionCallback getFunctionCallback(@NonNull String beanName, @Nullable String defaultDescription) {
//
Type beanType = FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), beanName); // Type beanType = FunctionContextUtils.findType(this.applicationContext.getBeanFactory(), beanName);
//
if (beanType == null) { // if (beanType == null) {
throw new IllegalArgumentException( // throw new IllegalArgumentException(
"Functional bean with name: " + beanName + " does not exist in the context."); // "Functional bean with name: " + beanName + " does not exist in the context.");
} // }
//
if (!Function.class.isAssignableFrom(FunctionTypeUtils.getRawType(beanType))) { // if (!Function.class.isAssignableFrom(FunctionTypeUtils.getRawType(beanType))) {
throw new IllegalArgumentException( // throw new IllegalArgumentException(
"Function call Bean must be of type Function. Found: " + beanType.getTypeName()); // "Function call Bean must be of type Function. Found: " + beanType.getTypeName());
} // }
//
Type functionInputType = TypeResolverHelper.getFunctionArgumentType(beanType, 0); // Type functionInputType = TypeResolverHelper.getFunctionArgumentType(beanType, 0);
//
Class<?> functionInputClass = FunctionTypeUtils.getRawType(functionInputType); // Class<?> functionInputClass = FunctionTypeUtils.getRawType(functionInputType);
String functionName = beanName; // String functionName = beanName;
String functionDescription = defaultDescription; // String functionDescription = defaultDescription;
//
if (!StringUtils.hasText(functionDescription)) { // if (!StringUtils.hasText(functionDescription)) {
// Look for a Description annotation on the bean // // Look for a Description annotation on the bean
Description descriptionAnnotation = applicationContext.findAnnotationOnBean(beanName, Description.class); // Description descriptionAnnotation = applicationContext.findAnnotationOnBean(beanName, Description.class);
//
if (descriptionAnnotation != null) { // if (descriptionAnnotation != null) {
functionDescription = descriptionAnnotation.value(); // functionDescription = descriptionAnnotation.value();
} // }
//
if (!StringUtils.hasText(functionDescription)) { // if (!StringUtils.hasText(functionDescription)) {
// Look for a JsonClassDescription annotation on the input class // // Look for a JsonClassDescription annotation on the input class
JsonClassDescription jsonClassDescriptionAnnotation = functionInputClass // JsonClassDescription jsonClassDescriptionAnnotation = functionInputClass
.getAnnotation(JsonClassDescription.class); // .getAnnotation(JsonClassDescription.class);
if (jsonClassDescriptionAnnotation != null) { // if (jsonClassDescriptionAnnotation != null) {
functionDescription = jsonClassDescriptionAnnotation.value(); // functionDescription = jsonClassDescriptionAnnotation.value();
} // }
} // }
//
if (!StringUtils.hasText(functionDescription)) { // if (!StringUtils.hasText(functionDescription)) {
throw new IllegalStateException("Could not determine function description." // throw new IllegalStateException("Could not determine function description."
+ "Please provide a description either as a default parameter, via @Description annotation on the bean " // + "Please provide a description either as a default parameter, via @Description annotation on the bean "
+ "or @JsonClassDescription annotation on the input class."); // + "or @JsonClassDescription annotation on the input class.");
} // }
} // }
//
Object bean = this.applicationContext.getBean(beanName); // Object bean = this.applicationContext.getBean(beanName);
//
if (bean instanceof Function<?, ?> function) { // if (bean instanceof Function<?, ?> function) {
return FunctionCallbackWrapper.builder(function) // return FunctionCallbackWrapper.builder(function)
.withName(functionName) // .withName(functionName)
.withSchemaType(this.schemaType) // .withSchemaType(this.schemaType)
.withDescription(functionDescription) // .withDescription(functionDescription)
.withInputType(functionInputClass) // .withInputType(functionInputClass)
.build(); // .build();
} // }
else { // else {
throw new IllegalArgumentException("Bean must be of type Function"); // throw new IllegalArgumentException("Bean must be of type Function");
} // }
} // }
//
} //}

View File

@ -153,13 +153,18 @@ public class BeanOutputParser<T> implements OutputParser<T> {
*/ */
@Override @Override
public String getFormat() { public String getFormat() {
String template = """ // String template = """
Your response should be in JSON format. // 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 any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.
Do not include markdown code blocks in your response. // Do not include markdown code blocks in your response.
Here is the JSON Schema instance your output must adhere to: // Here is the JSON Schema instance your output must adhere to:
```%s``` // ```%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); return String.format(template, this.jsonSchema);
} }

View File

@ -34,10 +34,12 @@ public class ListOutputParser extends AbstractConversionServiceOutputParser<List
@Override @Override
public String getFormat() { public String getFormat() {
return """ // return """
Your response should be a list of comma separated values // Your response should be a list of comma separated values
eg: `foo, bar, baz` // eg: `foo, bar, baz`
"""; // """;
return "Your response should be a list of comma separated values\n" +
"\t\t\t\teg: `foo, bar, baz`";
} }
@Override @Override

View File

@ -46,11 +46,14 @@ public class MapOutputParser extends AbstractMessageConverterOutputParser<Map<St
@Override @Override
public String getFormat() { public String getFormat() {
String raw = """ // String raw = """
Your response should be in JSON format. // Your response should be in JSON format.
The data structure for the JSON should match this Java class: %s // 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. // 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"); return String.format(raw, "java.util.HashMap");
} }