mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-06-13 11:14:38 +08:00
Feat: proxy 模块框架搭建
This commit is contained in:
@@ -17,4 +17,6 @@ import java.lang.annotation.Target;
|
||||
public @interface AIComponent {
|
||||
|
||||
String nodeId() default "";
|
||||
|
||||
String nodeName() default "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.yomahub.liteflow.ai.enums;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* AI 节点类型枚举
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public enum AITypeEnum {
|
||||
/**
|
||||
* AI对话 - 对应 NodeComponent
|
||||
*/
|
||||
CHAT("AIChat", NodeComponent.class),
|
||||
|
||||
/**
|
||||
* AI分类 - 对应 NodeSwitchComponent
|
||||
*/
|
||||
CLASSIFY("AIClassify", NodeSwitchComponent.class),
|
||||
|
||||
/**
|
||||
* AI检索 - 对应 NodeComponent
|
||||
*/
|
||||
RETRIEVAL("AIRetrieval", NodeComponent.class);
|
||||
|
||||
private final String type;
|
||||
private final Class<? extends NodeComponent> componentClass;
|
||||
|
||||
private static final Map<String, Class<? extends NodeComponent>> cache;
|
||||
|
||||
AITypeEnum(String type, Class<? extends NodeComponent> componentClass) {
|
||||
this.type = type;
|
||||
this.componentClass = componentClass;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Class<? extends NodeComponent> getComponentClass() {
|
||||
return componentClass;
|
||||
}
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(AITypeEnum.values()).collect(Collectors.toMap(AITypeEnum::getType, AITypeEnum::getComponentClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解获取对应的 NodeComponent 类
|
||||
* @param annotationType 注解类
|
||||
* @return 对应的 NodeComponent 类
|
||||
*/
|
||||
public static Class<? extends NodeComponent> fromAnnotationType(Class<?> annotationType) {
|
||||
return cache.get(annotationType.getSimpleName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package com.yomahub.liteflow.ai.proxy;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
import com.yomahub.liteflow.ai.proxy.handler.AbstractAIComponentHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.handler.ChatComponentHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.handler.ClassifyComponentHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.handler.RetrievalComponentHandler;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* AI组件工厂
|
||||
* 实现工厂模式,管理不同类型AI组件的创建
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public class AIComponentFactory {
|
||||
|
||||
private static final LFLog LOG = LFLoggerManager.getLogger(AIComponentFactory.class);
|
||||
|
||||
private final Map<Class<? extends Annotation>, AbstractAIComponentHandler<?>> handlerMap;
|
||||
|
||||
public AIComponentFactory() {
|
||||
this.handlerMap = new HashMap<>();
|
||||
initializeHandlers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化处理器映射
|
||||
*/
|
||||
private void initializeHandlers() {
|
||||
// 注册不同类型的AI组件处理器
|
||||
registerHandler(new ChatComponentHandler());
|
||||
registerHandler(new ClassifyComponentHandler());
|
||||
registerHandler(new RetrievalComponentHandler());
|
||||
|
||||
LOG.info("Initialized AI component handlers: {}", handlerMap.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册处理器
|
||||
*
|
||||
* @param handler 处理器实例
|
||||
*/
|
||||
private void registerHandler(AbstractAIComponentHandler<?> handler) {
|
||||
handlerMap.put(handler.getSupportedAnnotationType(), handler);
|
||||
LOG.debug("Registered handler: {} for annotation: {}",
|
||||
handler.getClass().getSimpleName(),
|
||||
handler.getSupportedAnnotationType().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建AI组件
|
||||
*
|
||||
* @param interfaceClass 接口类
|
||||
* @param beanName bean名称
|
||||
* @return NodeComponent实例,如果不是AI组件则返回null
|
||||
*/
|
||||
public NodeComponent createAIComponent(Class<?> interfaceClass, String beanName) {
|
||||
LOG.info("Attempting to create AI component for interface: {}, beanName: {}",
|
||||
interfaceClass.getName(), beanName);
|
||||
|
||||
// 检查是否是AI组件
|
||||
AIComponent aiComponent = interfaceClass.getAnnotation(AIComponent.class);
|
||||
if (Objects.isNull(aiComponent)) {
|
||||
LOG.debug("Interface {} is not an AI component", interfaceClass.getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 查找对应的处理器
|
||||
AbstractAIComponentHandler<?> handler = findHandler(interfaceClass);
|
||||
if (Objects.isNull(handler)) {
|
||||
LOG.warn("No handler found for AI component interface: {}", interfaceClass.getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 使用处理器创建组件
|
||||
try {
|
||||
NodeComponent component = handler.createAIComponent(interfaceClass, beanName, aiComponent);
|
||||
if (Objects.nonNull(component)) {
|
||||
LOG.info("Successfully created AI component: {} with handler: {}",
|
||||
beanName, handler.getClass().getSimpleName());
|
||||
}
|
||||
return component;
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to create AI component: {}", beanName, e);
|
||||
throw new RuntimeException("Failed to create AI component: " + beanName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找适合的处理器
|
||||
*
|
||||
* @param interfaceClass 接口类
|
||||
* @return 处理器实例,如果没有找到则返回null
|
||||
*/
|
||||
private AbstractAIComponentHandler<?> findHandler(Class<?> interfaceClass) {
|
||||
// 遍历所有支持的注解类型,查找匹配的处理器
|
||||
for (Map.Entry<Class<? extends Annotation>, AbstractAIComponentHandler<?>> entry : handlerMap.entrySet()) {
|
||||
Class<? extends Annotation> annotationType = entry.getKey();
|
||||
if (interfaceClass.isAnnotationPresent(annotationType)) {
|
||||
LOG.debug("Found handler: {} for annotation: {} on interface: {}",
|
||||
entry.getValue().getClass().getSimpleName(),
|
||||
annotationType.getSimpleName(),
|
||||
interfaceClass.getName());
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是AI组件接口
|
||||
*
|
||||
* @param interfaceClass 接口类
|
||||
* @return true如果是AI组件
|
||||
*/
|
||||
public boolean isAIComponent(Class<?> interfaceClass) {
|
||||
if (!interfaceClass.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否有AIComponent注解
|
||||
if (!interfaceClass.isAnnotationPresent(AIComponent.class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否有任何支持的AI注解
|
||||
for (Class<? extends Annotation> annotationType : handlerMap.keySet()) {
|
||||
if (interfaceClass.isAnnotationPresent(annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的注解类型
|
||||
*
|
||||
* @return 支持的注解类型集合
|
||||
*/
|
||||
public Map<Class<? extends Annotation>, AbstractAIComponentHandler<?>> getSupportedAnnotations() {
|
||||
return new HashMap<>(handlerMap);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.yomahub.liteflow.ai.proxy;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* AI组件后置处理器
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public class AIComponentPostProcessor implements BeanPostProcessor, Ordered {
|
||||
|
||||
private static final LFLog LOG = LFLoggerManager.getLogger(AIComponentPostProcessor.class);
|
||||
|
||||
private final AIComponentFactory aiComponentFactory = new AIComponentFactory();
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
Class<?> clazz = bean.getClass();
|
||||
|
||||
// 检查是否是AI组件接口
|
||||
if (aiComponentFactory.isAIComponent(clazz)) {
|
||||
LOG.info("Detected AI component interface: {} with beanName: {}", clazz.getName(), beanName);
|
||||
|
||||
try {
|
||||
// 使用工厂创建AI组件
|
||||
NodeComponent aiComponent = aiComponentFactory.createAIComponent(clazz, beanName);
|
||||
|
||||
if (Objects.nonNull(aiComponent)) {
|
||||
LOG.info("Successfully created AI component for interface: {}, replacing bean: {}",
|
||||
clazz.getName(), beanName);
|
||||
return aiComponent;
|
||||
} else {
|
||||
LOG.warn("Failed to create AI component for interface: {}, returning original bean",
|
||||
clazz.getName());
|
||||
return bean;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error creating AI component for interface: {}, beanName: {}",
|
||||
clazz.getName(), beanName, e);
|
||||
// 如果创建失败,返回原始bean而不是抛出异常
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
// 设置较高的优先级,确保在其他后置处理器之前执行
|
||||
return Ordered.HIGHEST_PRECEDENCE + 100;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.yomahub.liteflow.ai.proxy.handler;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
import com.yomahub.liteflow.ai.enums.AITypeEnum;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.exception.ProxyException;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
import com.yomahub.liteflow.util.SerialsUtil;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||
import net.bytebuddy.implementation.InvocationHandlerAdapter;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* AI组件处理器抽象基类
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public abstract class AbstractAIComponentHandler<T extends Annotation> {
|
||||
|
||||
protected final LFLog LOG = LFLoggerManager.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 获取对应的 AI 组件类型
|
||||
*
|
||||
* @return {@link AITypeEnum}
|
||||
*/
|
||||
public abstract AITypeEnum getAIType();
|
||||
|
||||
/**
|
||||
* 获取支持的注解类型
|
||||
*
|
||||
* @return 注解Class
|
||||
*/
|
||||
public abstract Class<T> getSupportedAnnotationType();
|
||||
|
||||
/**
|
||||
* 创建AI组件
|
||||
*
|
||||
* @param interfaceClass 接口类
|
||||
* @param beanName bean名称
|
||||
* @param aiComponent AI组件注解
|
||||
* @return NodeComponent实例
|
||||
*/
|
||||
public NodeComponent createAIComponent(Class<?> interfaceClass, String beanName, AIComponent aiComponent) {
|
||||
LOG.info("Creating AI component for interface: {}, beanName: {}, type: {}",
|
||||
interfaceClass.getName(), beanName, getAIType());
|
||||
|
||||
// 解析AI注解
|
||||
AIProxyWrapBean<T> wrapBean = parseAIAnnotations(interfaceClass, beanName, aiComponent);
|
||||
if (Objects.isNull(wrapBean)) {
|
||||
LOG.warn("Failed to parse AI annotations for interface: {}, beanName: {}",
|
||||
interfaceClass.getName(), beanName);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 创建代理组件
|
||||
return createProxyComponent(wrapBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析AI注解信息
|
||||
*
|
||||
* @param interfaceClass 接口类
|
||||
* @param beanName bean名称
|
||||
* @param aiComponent AI组件注解
|
||||
* @return 包装bean
|
||||
*/
|
||||
public AIProxyWrapBean<T> parseAIAnnotations(Class<?> interfaceClass, String beanName, AIComponent aiComponent) {
|
||||
LOG.info("Parsing AI annotations for interface: {}, beanName: {}", interfaceClass.getName(), beanName);
|
||||
|
||||
T aiAnnotation = findAIAnnotation(interfaceClass);
|
||||
// 如果没有找到 AI 注解,则记录警告并返回 null
|
||||
if (Objects.isNull(aiAnnotation)) {
|
||||
LOG.warn("No {} annotation found for interface: {}, beanName: {}",
|
||||
getSupportedAnnotationType().getSimpleName(), interfaceClass.getName(), beanName);
|
||||
return null;
|
||||
}
|
||||
|
||||
return createWrapBean(aiComponent, aiAnnotation, interfaceClass, beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找AI注解
|
||||
*
|
||||
* @param clazz 类
|
||||
* @return AI注解
|
||||
*/
|
||||
protected T findAIAnnotation(Class<?> clazz) {
|
||||
return clazz.getAnnotation(getSupportedAnnotationType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建包装Bean
|
||||
*
|
||||
* @param aiComponent AI组件注解
|
||||
* @param annotation 具体AI注解
|
||||
* @param interfaceClass 接口类
|
||||
* @param beanName bean名称
|
||||
* @return 包装bean
|
||||
*/
|
||||
protected abstract AIProxyWrapBean<T> createWrapBean(AIComponent aiComponent, T annotation,
|
||||
Class<?> interfaceClass, String beanName);
|
||||
|
||||
/**
|
||||
* 创建代理组件
|
||||
*
|
||||
* @param wrapBean 包装bean
|
||||
* @return NodeComponent实例
|
||||
*/
|
||||
private NodeComponent createProxyComponent(AIProxyWrapBean<T> wrapBean) {
|
||||
AITypeEnum aiType = getAIType();
|
||||
|
||||
Class<? extends NodeComponent> nodeComponentClass = aiType.getComponentClass();
|
||||
|
||||
// 创建 ByteBuddy 代理
|
||||
try {
|
||||
NodeComponent nodeComponent = new ByteBuddy()
|
||||
.subclass(nodeComponentClass)
|
||||
.name(generateProxyClassName(wrapBean))
|
||||
.implement(wrapBean.getInterfaceClass())
|
||||
.method(getInterceptMethodName())
|
||||
.intercept(InvocationHandlerAdapter.of(getInvocationHandler(wrapBean)))
|
||||
.annotateType(wrapBean.getAiComponent(), wrapBean.getAnnotation())
|
||||
.make()
|
||||
.load(this.getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
|
||||
.getLoaded()
|
||||
.newInstance();
|
||||
|
||||
nodeComponent.setNodeId(wrapBean.getNodeId());
|
||||
nodeComponent.setName(wrapBean.getNodeName());
|
||||
|
||||
LOG.info("Created AI component: {}, beanName: {}, type: {}",
|
||||
nodeComponent.getNodeId(), wrapBean.getBeanName(), aiType);
|
||||
|
||||
return nodeComponent;
|
||||
} catch (Exception e) {
|
||||
throw new ProxyException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代理类名称
|
||||
*
|
||||
* @param wrapBean 包装bean
|
||||
* @return 代理类名称
|
||||
*/
|
||||
private String generateProxyClassName(AIProxyWrapBean<T> wrapBean) {
|
||||
return StrUtil.format("{}$ByteBuddy${}${}",
|
||||
wrapBean.getInterfaceClass().getName(),
|
||||
wrapBean.getAiComponent().nodeId(),
|
||||
SerialsUtil.generateShortUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取InvocationHandler
|
||||
*
|
||||
* @param wrapBean 包装bean
|
||||
* @return InvocationHandler实例
|
||||
*/
|
||||
protected abstract InvocationHandler getInvocationHandler(AIProxyWrapBean<T> wrapBean);
|
||||
|
||||
/**
|
||||
* 获取拦截方法名称
|
||||
*
|
||||
* @return 拦截方法名称
|
||||
*/
|
||||
protected abstract ElementMatcher<? super MethodDescription> getInterceptMethodName();
|
||||
|
||||
/**
|
||||
* 判断是否支持指定的注解类型
|
||||
*
|
||||
* @param annotationType 注解类型
|
||||
* @return true如果支持
|
||||
*/
|
||||
public boolean supports(Class<? extends Annotation> annotationType) {
|
||||
return getSupportedAnnotationType().equals(annotationType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yomahub.liteflow.ai.proxy.handler;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIChat;
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
import com.yomahub.liteflow.ai.enums.AITypeEnum;
|
||||
import com.yomahub.liteflow.ai.proxy.invocation.ChatAIInvocationHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
||||
/**
|
||||
* 聊天组件处理器
|
||||
* 具体策略实现
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public class ChatComponentHandler extends AbstractAIComponentHandler<AIChat> {
|
||||
|
||||
private static final String INTERCEPT_METHOD_NAME = "process";
|
||||
|
||||
@Override
|
||||
public AITypeEnum getAIType() {
|
||||
return AITypeEnum.CHAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AIChat> getSupportedAnnotationType() {
|
||||
return AIChat.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AIProxyWrapBean<AIChat> createWrapBean(AIComponent aiComponent, AIChat annotation,
|
||||
Class<?> interfaceClass, String beanName) {
|
||||
return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvocationHandler getInvocationHandler(AIProxyWrapBean<AIChat> wrapBean) {
|
||||
return new ChatAIInvocationHandler(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ElementMatcher<? super MethodDescription> getInterceptMethodName() {
|
||||
return ElementMatchers.named(INTERCEPT_METHOD_NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yomahub.liteflow.ai.proxy.handler;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIClassify;
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
import com.yomahub.liteflow.ai.enums.AITypeEnum;
|
||||
import com.yomahub.liteflow.ai.proxy.invocation.ClassifyAIInvocationHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
||||
/**
|
||||
* 分类组件处理器
|
||||
* 具体策略实现
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public class ClassifyComponentHandler extends AbstractAIComponentHandler<AIClassify> {
|
||||
|
||||
private static final String INTERCEPT_METHOD_NAME = "processSwitch";
|
||||
|
||||
@Override
|
||||
public AITypeEnum getAIType() {
|
||||
return AITypeEnum.CLASSIFY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AIClassify> getSupportedAnnotationType() {
|
||||
return AIClassify.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AIProxyWrapBean<AIClassify> createWrapBean(AIComponent aiComponent, AIClassify annotation,
|
||||
Class<?> interfaceClass, String beanName) {
|
||||
return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvocationHandler getInvocationHandler(AIProxyWrapBean<AIClassify> wrapBean) {
|
||||
return new ClassifyAIInvocationHandler(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ElementMatcher<? super MethodDescription> getInterceptMethodName() {
|
||||
return ElementMatchers.named(INTERCEPT_METHOD_NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yomahub.liteflow.ai.proxy.handler;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
import com.yomahub.liteflow.ai.annotation.AIRetrieval;
|
||||
import com.yomahub.liteflow.ai.enums.AITypeEnum;
|
||||
import com.yomahub.liteflow.ai.proxy.invocation.RetrievalAIInvocationHandler;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
|
||||
/**
|
||||
* 检索组件处理器
|
||||
* 具体策略实现
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
public class RetrievalComponentHandler extends AbstractAIComponentHandler<AIRetrieval> {
|
||||
|
||||
private static final String INTERCEPT_METHOD_NAME = "process";
|
||||
|
||||
@Override
|
||||
public AITypeEnum getAIType() {
|
||||
return AITypeEnum.RETRIEVAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AIRetrieval> getSupportedAnnotationType() {
|
||||
return AIRetrieval.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AIProxyWrapBean<AIRetrieval> createWrapBean(AIComponent aiComponent, AIRetrieval annotation,
|
||||
Class<?> interfaceClass, String beanName) {
|
||||
return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvocationHandler getInvocationHandler(AIProxyWrapBean<AIRetrieval> wrapBean) {
|
||||
return new RetrievalAIInvocationHandler(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ElementMatcher<? super MethodDescription> getInterceptMethodName() {
|
||||
return ElementMatchers.named(INTERCEPT_METHOD_NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.yomahub.liteflow.ai.proxy.invocation;
|
||||
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 抽象AI调用处理器
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public abstract class AbstractAIInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final LFLog LOG = LFLoggerManager.getLogger(this.getClass());
|
||||
|
||||
protected AIProxyWrapBean<?> wrapBean;
|
||||
|
||||
public AbstractAIInvocationHandler(AIProxyWrapBean<?> wrapBean) {
|
||||
this.wrapBean = wrapBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
return executeAIProcess((NodeComponent) proxy, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行AI节点处理逻辑
|
||||
*
|
||||
* @param nodeComponent AI节点组件
|
||||
* @param args
|
||||
* @return 处理结果
|
||||
*/
|
||||
protected abstract Object executeAIProcess(NodeComponent nodeComponent, Object[] args);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.yomahub.liteflow.ai.proxy.invocation;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIChat;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
/**
|
||||
* 聊天组件的调用处理器
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public class ChatAIInvocationHandler extends AbstractAIInvocationHandler {
|
||||
|
||||
public ChatAIInvocationHandler(AIProxyWrapBean<AIChat> wrapBean) {
|
||||
super(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.yomahub.liteflow.ai.proxy.invocation;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIClassify;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
/**
|
||||
* 分类组件的调用处理器
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public class ClassifyAIInvocationHandler extends AbstractAIInvocationHandler {
|
||||
|
||||
public ClassifyAIInvocationHandler(AIProxyWrapBean<AIClassify> wrapBean) {
|
||||
super(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.yomahub.liteflow.ai.proxy.invocation;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIRetrieval;
|
||||
import com.yomahub.liteflow.ai.proxy.wrap.AIProxyWrapBean;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
/**
|
||||
* RAG组件的调用处理器
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public class RetrievalAIInvocationHandler extends AbstractAIInvocationHandler {
|
||||
|
||||
public RetrievalAIInvocationHandler(AIProxyWrapBean<AIRetrieval> wrapBean) {
|
||||
super(wrapBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.yomahub.liteflow.ai.proxy.wrap;
|
||||
|
||||
import com.yomahub.liteflow.ai.annotation.AIComponent;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author 苍镜月
|
||||
* @since TODO
|
||||
*/
|
||||
|
||||
public class AIProxyWrapBean<T extends Annotation> {
|
||||
|
||||
protected AIComponent aiComponent;
|
||||
|
||||
protected T annotation;
|
||||
|
||||
protected Class<?> interfaceClass;
|
||||
|
||||
protected String beanName;
|
||||
|
||||
public AIProxyWrapBean() {
|
||||
}
|
||||
|
||||
public AIProxyWrapBean(AIComponent aiComponent, T annotation,
|
||||
Class<?> interfaceClass, String beanName) {
|
||||
this.aiComponent = aiComponent;
|
||||
this.annotation = annotation;
|
||||
this.interfaceClass = interfaceClass;
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public String getNodeId() {
|
||||
return aiComponent.nodeId();
|
||||
}
|
||||
|
||||
public String getNodeName() {
|
||||
return aiComponent.nodeName();
|
||||
}
|
||||
|
||||
public AIComponent getAiComponent() {
|
||||
return aiComponent;
|
||||
}
|
||||
|
||||
public T getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public Class<?> getInterfaceClass() {
|
||||
return interfaceClass;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
public void setAiComponent(AIComponent aiComponent) {
|
||||
this.aiComponent = aiComponent;
|
||||
}
|
||||
|
||||
public void setAnnotation(T annotation) {
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
public void setInterfaceClass(Class<?> interfaceClass) {
|
||||
this.interfaceClass = interfaceClass;
|
||||
}
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user