Commit 6a3cafb41ee43b4f27d995a892a8fd013784bbe3
1 parent
c71b8b3c
适配jdk8 - 2,这个地方不会改
Showing
1 changed file
with
115 additions
and
113 deletions
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 | -// | 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 | + // TODO: 2024/3/16 fansili 适配jdk8 | ||
| 112 | + return null; | ||
| 111 | // if (bean instanceof Function<?, ?> function) { | 113 | // if (bean instanceof Function<?, ?> function) { |
| 112 | // return FunctionCallbackWrapper.builder(function) | 114 | // return FunctionCallbackWrapper.builder(function) |
| 113 | // .withName(functionName) | 115 | // .withName(functionName) |
| @@ -119,6 +121,6 @@ | @@ -119,6 +121,6 @@ | ||
| 119 | // else { | 121 | // else { |
| 120 | // throw new IllegalArgumentException("Bean must be of type Function"); | 122 | // throw new IllegalArgumentException("Bean must be of type Function"); |
| 121 | // } | 123 | // } |
| 122 | -// } | ||
| 123 | -// | ||
| 124 | -//} | 124 | + } |
| 125 | + | ||
| 126 | +} |