diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/annotation/AIComponent.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/annotation/AIComponent.java index 71507dacf..d2256e7ca 100644 --- a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/annotation/AIComponent.java +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/annotation/AIComponent.java @@ -17,4 +17,6 @@ import java.lang.annotation.Target; public @interface AIComponent { String nodeId() default ""; + + String nodeName() default ""; } diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/enums/AITypeEnum.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/enums/AITypeEnum.java new file mode 100644 index 000000000..383a90dc5 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/enums/AITypeEnum.java @@ -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 componentClass; + + private static final Map> cache; + + AITypeEnum(String type, Class componentClass) { + this.type = type; + this.componentClass = componentClass; + } + + public String getType() { + return type; + } + + public Class getComponentClass() { + return componentClass; + } + + static { + cache = Arrays.stream(AITypeEnum.values()).collect(Collectors.toMap(AITypeEnum::getType, AITypeEnum::getComponentClass)); + } + + /** + * 根据注解获取对应的 NodeComponent 类 + * @param annotationType 注解类 + * @return 对应的 NodeComponent 类 + */ + public static Class fromAnnotationType(Class annotationType) { + return cache.get(annotationType.getSimpleName()); + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentFactory.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentFactory.java new file mode 100644 index 000000000..d443416a1 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentFactory.java @@ -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, 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, AbstractAIComponentHandler> entry : handlerMap.entrySet()) { + Class 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 annotationType : handlerMap.keySet()) { + if (interfaceClass.isAnnotationPresent(annotationType)) { + return true; + } + } + + return false; + } + + /** + * 获取支持的注解类型 + * + * @return 支持的注解类型集合 + */ + public Map, AbstractAIComponentHandler> getSupportedAnnotations() { + return new HashMap<>(handlerMap); + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentPostProcessor.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentPostProcessor.java new file mode 100644 index 000000000..a95e57ecc --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/AIComponentPostProcessor.java @@ -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; + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/AbstractAIComponentHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/AbstractAIComponentHandler.java new file mode 100644 index 000000000..55bf7b32f --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/AbstractAIComponentHandler.java @@ -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 { + + protected final LFLog LOG = LFLoggerManager.getLogger(this.getClass()); + + /** + * 获取对应的 AI 组件类型 + * + * @return {@link AITypeEnum} + */ + public abstract AITypeEnum getAIType(); + + /** + * 获取支持的注解类型 + * + * @return 注解Class + */ + public abstract Class 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 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 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 createWrapBean(AIComponent aiComponent, T annotation, + Class interfaceClass, String beanName); + + /** + * 创建代理组件 + * + * @param wrapBean 包装bean + * @return NodeComponent实例 + */ + private NodeComponent createProxyComponent(AIProxyWrapBean wrapBean) { + AITypeEnum aiType = getAIType(); + + Class 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 wrapBean) { + return StrUtil.format("{}$ByteBuddy${}${}", + wrapBean.getInterfaceClass().getName(), + wrapBean.getAiComponent().nodeId(), + SerialsUtil.generateShortUUID()); + } + + /** + * 获取InvocationHandler + * + * @param wrapBean 包装bean + * @return InvocationHandler实例 + */ + protected abstract InvocationHandler getInvocationHandler(AIProxyWrapBean wrapBean); + + /** + * 获取拦截方法名称 + * + * @return 拦截方法名称 + */ + protected abstract ElementMatcher getInterceptMethodName(); + + /** + * 判断是否支持指定的注解类型 + * + * @param annotationType 注解类型 + * @return true如果支持 + */ + public boolean supports(Class annotationType) { + return getSupportedAnnotationType().equals(annotationType); + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ChatComponentHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ChatComponentHandler.java new file mode 100644 index 000000000..3c3c37df3 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ChatComponentHandler.java @@ -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 { + + private static final String INTERCEPT_METHOD_NAME = "process"; + + @Override + public AITypeEnum getAIType() { + return AITypeEnum.CHAT; + } + + @Override + public Class getSupportedAnnotationType() { + return AIChat.class; + } + + @Override + protected AIProxyWrapBean createWrapBean(AIComponent aiComponent, AIChat annotation, + Class interfaceClass, String beanName) { + return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName); + } + + @Override + protected InvocationHandler getInvocationHandler(AIProxyWrapBean wrapBean) { + return new ChatAIInvocationHandler(wrapBean); + } + + @Override + protected ElementMatcher getInterceptMethodName() { + return ElementMatchers.named(INTERCEPT_METHOD_NAME); + } +} \ No newline at end of file diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ClassifyComponentHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ClassifyComponentHandler.java new file mode 100644 index 000000000..51ad45c9c --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/ClassifyComponentHandler.java @@ -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 { + + private static final String INTERCEPT_METHOD_NAME = "processSwitch"; + + @Override + public AITypeEnum getAIType() { + return AITypeEnum.CLASSIFY; + } + + @Override + public Class getSupportedAnnotationType() { + return AIClassify.class; + } + + @Override + protected AIProxyWrapBean createWrapBean(AIComponent aiComponent, AIClassify annotation, + Class interfaceClass, String beanName) { + return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName); + } + + @Override + protected InvocationHandler getInvocationHandler(AIProxyWrapBean wrapBean) { + return new ClassifyAIInvocationHandler(wrapBean); + } + + @Override + protected ElementMatcher getInterceptMethodName() { + return ElementMatchers.named(INTERCEPT_METHOD_NAME); + } +} \ No newline at end of file diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/RetrievalComponentHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/RetrievalComponentHandler.java new file mode 100644 index 000000000..3af76f2d4 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/handler/RetrievalComponentHandler.java @@ -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 { + + private static final String INTERCEPT_METHOD_NAME = "process"; + + @Override + public AITypeEnum getAIType() { + return AITypeEnum.RETRIEVAL; + } + + @Override + public Class getSupportedAnnotationType() { + return AIRetrieval.class; + } + + @Override + protected AIProxyWrapBean createWrapBean(AIComponent aiComponent, AIRetrieval annotation, + Class interfaceClass, String beanName) { + return new AIProxyWrapBean<>(aiComponent, annotation, interfaceClass, beanName); + } + + @Override + protected InvocationHandler getInvocationHandler(AIProxyWrapBean wrapBean) { + return new RetrievalAIInvocationHandler(wrapBean); + } + + @Override + protected ElementMatcher getInterceptMethodName() { + return ElementMatchers.named(INTERCEPT_METHOD_NAME); + } +} \ No newline at end of file diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/AbstractAIInvocationHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/AbstractAIInvocationHandler.java new file mode 100644 index 000000000..6f4d2aca1 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/AbstractAIInvocationHandler.java @@ -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); +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ChatAIInvocationHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ChatAIInvocationHandler.java new file mode 100644 index 000000000..e860a7686 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ChatAIInvocationHandler.java @@ -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 wrapBean) { + super(wrapBean); + } + + @Override + protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) { + + return null; + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ClassifyAIInvocationHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ClassifyAIInvocationHandler.java new file mode 100644 index 000000000..ec6a20b5a --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/ClassifyAIInvocationHandler.java @@ -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 wrapBean) { + super(wrapBean); + } + + @Override + protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) { + return null; + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/RetrievalAIInvocationHandler.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/RetrievalAIInvocationHandler.java new file mode 100644 index 000000000..9b2ad7ce9 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/invocation/RetrievalAIInvocationHandler.java @@ -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 wrapBean) { + super(wrapBean); + } + + @Override + protected Object executeAIProcess(NodeComponent nodeComponent, Object[] args) { + return null; + } +} diff --git a/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/wrap/AIProxyWrapBean.java b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/wrap/AIProxyWrapBean.java new file mode 100644 index 000000000..8c6838f86 --- /dev/null +++ b/liteflow-ai/liteflow-ai-core/src/main/java/com/yomahub/liteflow/ai/proxy/wrap/AIProxyWrapBean.java @@ -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 { + + 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; + } +}