推进框架中的模块注册机制; 完善启动逻辑流程。

- 调整 InteractionFlowContext 为抽象类,实现者的模块上下文应当继承自该类。
- 完善 Agent 启动类具体逻辑
- 取消 Agent 类中 launchRunners 中关闭虚拟线程池的行为,交由JVM等待线程关闭,而非直接停止整个进程。
- 调整原hook注解分别为 BeforeExecute 、 AfterExecute,该注解用于模块抽象类的子类时可抽取重复逻辑
- 新增 Init 注解,用于执行初始化逻辑,可通过 order 属性指定顺序,默认为 0
- ModuleRegisterFactory 中新增‘加载 Init 注解标注的方法’的相关逻辑
- ModuleCheckFactory 添加对于 Init 注解的校验
- 完善了 ModuleProxyFactory 中设置代理实例的内容,可同时添加pre、post hook逻辑
This commit is contained in:
2025-08-06 00:17:10 +08:00
parent 507917157d
commit b1ed79ae9d
21 changed files with 232 additions and 60 deletions

1
.idea/.gitignore generated vendored
View File

@@ -6,3 +6,4 @@
# Datasource local storage ignored files # Datasource local storage ignored files
/dataSources/ /dataSources/
/dataSources.local.xml /dataSources.local.xml
/inspectionProfiles/Project_Default.xml

View File

@@ -1,4 +1,5 @@
autoDetectedPackages: autoDetectedPackages:
- module
- work.slhaf - work.slhaf
enableAutoDetect: true enableAutoDetect: true
entryDisplayConfig: entryDisplayConfig:

View File

@@ -26,7 +26,6 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.36</version> <version>1.18.36</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View File

@@ -1,8 +1,10 @@
package work.slhaf.partner.api; package work.slhaf.partner.api;
import work.slhaf.partner.api.entity.AgentContext; import work.slhaf.partner.api.exception.AgentLaunchFailedException;
import work.slhaf.partner.api.factory.AgentRegisterFactory; import work.slhaf.partner.api.factory.AgentRegisterFactory;
import work.slhaf.partner.api.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.flow.AgentInteraction; import work.slhaf.partner.api.flow.AgentInteraction;
import work.slhaf.partner.api.flow.entity.InteractionFlowContext;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -14,23 +16,38 @@ import java.util.concurrent.Executors;
*/ */
public class Agent { public class Agent {
private static final List<Runnable> runners = new ArrayList<>(); private final List<Runnable> runners = new ArrayList<>();
private final Class<?> applicationClass;
private final InteractionFlowContext interactionContext;
public static void run(Class<?> clazz) { private Agent(Class<?> clazz, InteractionFlowContext interactionContext) {
AgentContext context = AgentRegisterFactory.launch(clazz.getPackage().getName()); this.applicationClass = clazz;
AgentInteraction.launch(context); this.interactionContext = interactionContext;
}
public static Agent newAgent(Class<?> clazz, InteractionFlowContext interactionContext) {
if (clazz == null || interactionContext == null) {
throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null");
}
return new Agent(clazz, interactionContext);
}
public void run() {
List<MetaModule> moduleList = AgentRegisterFactory.launch(applicationClass.getPackage().getName());
AgentInteraction.launch(moduleList, interactionContext);
launchRunners(); launchRunners();
} }
private static void launchRunners() {
private void launchRunners() {
ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor(); ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
for (Runnable runner : runners) { for (Runnable runner : runners) {
executorService.execute(runner); executorService.execute(runner);
} }
executorService.close();
} }
public static void addRunner(Runnable runnable) { public Agent addRunners(Runnable... runnable) {
runners.add(runnable); runners.addAll(List.of(runnable));
return this;
} }
} }

View File

@@ -1,8 +1,10 @@
package work.slhaf.partner.api.entity; package work.slhaf.partner.api.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.factory.module.pojo.MetaModule;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@@ -14,4 +16,5 @@ public class AgentContext {
private HashMap<Class<?>, Object> capabilityHolderInstances; private HashMap<Class<?>, Object> capabilityHolderInstances;
private Set<Class<?>> cores; private Set<Class<?>> cores;
private Set<Class<?>> capabilities; private Set<Class<?>> capabilities;
private List<MetaModule> moduleList;
} }

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.exception;
public class AgentLaunchFailedException extends RuntimeException {
public AgentLaunchFailedException(String message, Throwable cause) {
super("Agent 启动失败: " + message, cause);
}
public AgentLaunchFailedException(String message) {
super("Agent 启动失败: " + message);
}
}

View File

@@ -1,8 +1,6 @@
package work.slhaf.partner.api.factory; package work.slhaf.partner.api.factory;
import cn.hutool.core.bean.BeanUtil;
import org.reflections.util.ClasspathHelper; import org.reflections.util.ClasspathHelper;
import work.slhaf.partner.api.entity.AgentContext;
import work.slhaf.partner.api.factory.capability.CapabilityCheckFactory; import work.slhaf.partner.api.factory.capability.CapabilityCheckFactory;
import work.slhaf.partner.api.factory.capability.CapabilityInjectFactory; import work.slhaf.partner.api.factory.capability.CapabilityInjectFactory;
import work.slhaf.partner.api.factory.capability.CapabilityRegisterFactory; import work.slhaf.partner.api.factory.capability.CapabilityRegisterFactory;
@@ -14,6 +12,7 @@ import work.slhaf.partner.api.factory.module.ModuleCheckFactory;
import work.slhaf.partner.api.factory.module.ModulePreHookExecuteFactory; import work.slhaf.partner.api.factory.module.ModulePreHookExecuteFactory;
import work.slhaf.partner.api.factory.module.ModuleProxyFactory; import work.slhaf.partner.api.factory.module.ModuleProxyFactory;
import work.slhaf.partner.api.factory.module.ModuleRegisterFactory; import work.slhaf.partner.api.factory.module.ModuleRegisterFactory;
import work.slhaf.partner.api.factory.module.pojo.MetaModule;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
@@ -27,7 +26,7 @@ public class AgentRegisterFactory {
private AgentRegisterFactory() { private AgentRegisterFactory() {
} }
public static AgentContext launch(String packageName) { public static List<MetaModule> launch(String packageName) {
urls.addAll(packageNameToURL(packageName)); urls.addAll(packageNameToURL(packageName));
AgentRegisterContext registerContext = new AgentRegisterContext(urls); AgentRegisterContext registerContext = new AgentRegisterContext(urls);
//流程 //流程
@@ -46,11 +45,10 @@ public class AgentRegisterFactory {
//. 执行模块PreHook逻辑 //. 执行模块PreHook逻辑
new ModulePreHookExecuteFactory().execute(registerContext); new ModulePreHookExecuteFactory().execute(registerContext);
AgentContext agentContext = new AgentContext(); return registerContext.getModuleFactoryContext().getModuleList();
BeanUtil.copyProperties(registerContext, agentContext);
return agentContext;
} }
/** /**
* 添加可扫描包 * 添加可扫描包
* @param packageName 指定的包名 * @param packageName 指定的包名

View File

@@ -14,4 +14,5 @@ public class ModuleFactoryContext {
private List<MetaModule> moduleList = new ArrayList<>(); private List<MetaModule> moduleList = new ArrayList<>();
private HashMap<Class<?>,Set<MetaMethod>> preHookMethods = new HashMap<>(); private HashMap<Class<?>,Set<MetaMethod>> preHookMethods = new HashMap<>();
private HashMap<Class<?>,Set<MetaMethod>> postHookMethods = new HashMap<>(); private HashMap<Class<?>,Set<MetaMethod>> postHookMethods = new HashMap<>();
private HashMap<Class<?>,Set<MetaMethod>> initHookMethods = new HashMap<>();
} }

View File

@@ -1,12 +1,14 @@
package work.slhaf.partner.api.factory.module; package work.slhaf.partner.api.factory.module;
import cn.hutool.core.util.ClassUtil;
import org.reflections.Reflections; import org.reflections.Reflections;
import work.slhaf.partner.api.factory.AgentBaseFactory; import work.slhaf.partner.api.factory.AgentBaseFactory;
import work.slhaf.partner.api.factory.config.ModelConfigManager; import work.slhaf.partner.api.factory.config.ModelConfigManager;
import work.slhaf.partner.api.factory.context.AgentRegisterContext; import work.slhaf.partner.api.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.factory.module.annotation.After; import work.slhaf.partner.api.factory.module.annotation.AfterExecute;
import work.slhaf.partner.api.factory.module.annotation.AgentModule; import work.slhaf.partner.api.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.factory.module.annotation.Before; import work.slhaf.partner.api.factory.module.annotation.BeforeExecute;
import work.slhaf.partner.api.factory.module.annotation.Init;
import work.slhaf.partner.api.factory.module.exception.ModuleCheckException; import work.slhaf.partner.api.factory.module.exception.ModuleCheckException;
import work.slhaf.partner.api.flow.abstracts.ActivateModel; import work.slhaf.partner.api.flow.abstracts.ActivateModel;
import work.slhaf.partner.api.flow.abstracts.AgentInteractionModule; import work.slhaf.partner.api.flow.abstracts.AgentInteractionModule;
@@ -68,14 +70,35 @@ public class ModuleCheckFactory extends AgentBaseFactory {
} }
private void hookLocationCheck() { private void hookLocationCheck() {
//检查@After注解 //检查@AfterExecute注解
postHookLocationCheck(); postHookLocationCheck();
//检查@Before注解 //检查@BeforeExecute注解
preHookLocationCheck(); preHookLocationCheck();
//检查@Init注解
initHookLocationCheck();
//检查@AgentModule注解是否只位于普通类上
agentModuleLocationCheck();
}
private void agentModuleLocationCheck() {
Set<Class<?>> types = reflections.getTypesAnnotatedWith(AgentModule.class);
for (Class<?> type : types) {
if (!ClassUtil.isNormalClass(type)) {
throw new ModuleCheckException("AgentModule 注解仅能位于普通类上! 异常类信息: " + type.getSimpleName());
}
}
}
private void initHookLocationCheck() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(Init.class);
Set<Class<?>> types = methods.stream()
.map(Method::getDeclaringClass)
.collect(Collectors.toSet());
checkLocation(types);
} }
private void preHookLocationCheck() { private void preHookLocationCheck() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(Before.class); Set<Method> methods = reflections.getMethodsAnnotatedWith(BeforeExecute.class);
Set<Class<?>> types = methods.stream() Set<Class<?>> types = methods.stream()
.map(Method::getDeclaringClass) .map(Method::getDeclaringClass)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
@@ -84,7 +107,7 @@ public class ModuleCheckFactory extends AgentBaseFactory {
private void postHookLocationCheck() { private void postHookLocationCheck() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(After.class); Set<Method> methods = reflections.getMethodsAnnotatedWith(AfterExecute.class);
Set<Class<?>> types = methods.stream() Set<Class<?>> types = methods.stream()
.map(Method::getDeclaringClass) .map(Method::getDeclaringClass)
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View File

@@ -1,9 +1,6 @@
package work.slhaf.partner.api.factory.module; package work.slhaf.partner.api.factory.module;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.*; import net.bytebuddy.implementation.bind.annotation.*;
import net.bytebuddy.matcher.ElementMatchers;
import work.slhaf.partner.api.factory.AgentBaseFactory; import work.slhaf.partner.api.factory.AgentBaseFactory;
import work.slhaf.partner.api.factory.context.AgentRegisterContext; import work.slhaf.partner.api.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.factory.context.ModuleFactoryContext; import work.slhaf.partner.api.factory.context.ModuleFactoryContext;
@@ -11,59 +8,81 @@ import work.slhaf.partner.api.factory.module.exception.ModuleInstanceGenerateFai
import work.slhaf.partner.api.factory.module.exception.ModuleProxyGenerateFailedException; import work.slhaf.partner.api.factory.module.exception.ModuleProxyGenerateFailedException;
import work.slhaf.partner.api.factory.module.pojo.MetaMethod; import work.slhaf.partner.api.factory.module.pojo.MetaMethod;
import work.slhaf.partner.api.factory.module.pojo.MetaModule; import work.slhaf.partner.api.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.flow.abstracts.AgentInteractionModule;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Comparator; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* 通过扫描注解<code>@Before</code>获取到各个模块的后hook逻辑并通过动态代理添加到执行逻辑之后 * 通过扫描注解<code>@BeforeExecute</code>获取到各个模块的后hook逻辑并通过动态代理添加到执行逻辑之后
*/ */
public class ModuleProxyFactory extends AgentBaseFactory { public class ModuleProxyFactory extends AgentBaseFactory {
private List<MetaModule> moduleList; private List<MetaModule> moduleList;
private HashMap<Class<?>, Set<MetaMethod>> postHookMethods; private HashMap<Class<?>, Set<MetaMethod>> postHookMethods;
private HashMap<Class<?>, Set<MetaMethod>> preHookMethods;
@Override @Override
protected void setVariables(AgentRegisterContext context) { protected void setVariables(AgentRegisterContext context) {
ModuleFactoryContext factoryContext = context.getModuleFactoryContext(); ModuleFactoryContext factoryContext = context.getModuleFactoryContext();
moduleList = factoryContext.getModuleList(); moduleList = factoryContext.getModuleList();
postHookMethods = factoryContext.getPostHookMethods(); postHookMethods = factoryContext.getPostHookMethods();
preHookMethods = factoryContext.getPreHookMethods();
} }
@Override @Override
protected void run() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { protected void run() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//TODO 生成实例、并通过动态代理添加PostHook逻辑 //TODO 填充具体逻辑
generateInstances(); generateInstances();
setPostHookProxy(); setHookProxy();
} }
private void setPostHookProxy() { private void setHookProxy() {
for (MetaModule module : moduleList) { for (MetaModule module : moduleList) {
Class<?> clazz = module.getClazz(); Class<?> clazz = module.getClazz();
try { try {
Class<?> proxyClass = new ByteBuddy() MethodsListRecord record = getHookMethodsList(clazz);
.subclass(clazz) //生成实例,
.method(ElementMatchers.isOverriddenFrom(AgentInteractionModule.class)) generateProxiedInstances(record);
.intercept(MethodDelegation.to(new ModuleProxyInterceptor(postHookMethods.get(clazz).stream().sorted(Comparator.comparing(MetaMethod::getOrder)).toList())))
.make()
.load(ModuleProxyFactory.class.getClassLoader())
.getLoaded();
AgentInteractionModule interactionModule = (AgentInteractionModule) proxyClass.getConstructor().newInstance();
//TODO 检测代理写法是否正确
//TODO 添加ModuleManager,负责统一管理Module的加载、卸载
} catch (Exception e) { } catch (Exception e) {
throw new ModuleProxyGenerateFailedException("创建代理对象失败: " + clazz.getSimpleName(), e); throw new ModuleProxyGenerateFailedException("创建代理对象失败: " + clazz.getSimpleName(), e);
} }
} }
} }
private void generateProxiedInstances(MethodsListRecord record) {
}
private MethodsListRecord getHookMethodsList(Class<?> clazz) {
List<MetaMethod> post = new ArrayList<>();
List<MetaMethod> pre = new ArrayList<>();
//获取该类本身的hook逻辑
getHookMethodsList(post, pre, clazz);
//获取它所继承、实现的抽象类或接口, 以AgentInteractionModule、ActiveModel为终点
List<Class<?>> classes = getExtendedClasses(clazz);
//获取这些类中的hook逻辑
getHookMethodsList(post, pre, classes);
return new MethodsListRecord(post, pre);
}
private void getHookMethodsList(List<MetaMethod> post, List<MetaMethod> pre, List<Class<?>> classes) {
}
private List<Class<?>> getExtendedClasses(Class<?> clazz) {
return null;
}
private void getHookMethodsList(List<MetaMethod> post, List<MetaMethod> pre, Class<?> clazz) {
}
private void generateInstances() { private void generateInstances() {
for (MetaModule metaModule : moduleList) { for (MetaModule metaModule : moduleList) {
try { try {
@@ -78,19 +97,27 @@ public class ModuleProxyFactory extends AgentBaseFactory {
private static class ModuleProxyInterceptor { private static class ModuleProxyInterceptor {
private List<MetaMethod> postHookMethods; private final List<MetaMethod> postHookMethods;
private final List<MetaMethod> preHookMethods;
private ModuleProxyInterceptor(List<MetaMethod> postHookMethods) { private ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
this.postHookMethods = postHookMethods; this.postHookMethods = postHookMethods;
this.preHookMethods = preHookMethods;
} }
@RuntimeType @RuntimeType
public Object intercept(@Origin Method method, @AllArguments Object[] allArguments, @SuperCall Callable<?> zuper, @This Object proxy) throws Exception { public Object intercept(@Origin Method method, @AllArguments Object[] allArguments, @SuperCall Callable<?> zuper, @This Object proxy) throws Exception {
for (MetaMethod metaMethod : preHookMethods) {
metaMethod.getMethod().invoke(proxy);
}
Object res = zuper.call(); Object res = zuper.call();
for (MetaMethod metaMethod : postHookMethods) { for (MetaMethod metaMethod : postHookMethods) {
metaMethod.getMethod().invoke(proxy, allArguments); metaMethod.getMethod().invoke(proxy);
} }
return res; return res;
} }
} }
record MethodsListRecord(List<MetaMethod> post, List<MetaMethod> pre) {
}
} }

View File

@@ -4,9 +4,10 @@ import org.reflections.Reflections;
import work.slhaf.partner.api.factory.AgentBaseFactory; import work.slhaf.partner.api.factory.AgentBaseFactory;
import work.slhaf.partner.api.factory.context.AgentRegisterContext; import work.slhaf.partner.api.factory.context.AgentRegisterContext;
import work.slhaf.partner.api.factory.context.ModuleFactoryContext; import work.slhaf.partner.api.factory.context.ModuleFactoryContext;
import work.slhaf.partner.api.factory.module.annotation.After; import work.slhaf.partner.api.factory.module.annotation.AfterExecute;
import work.slhaf.partner.api.factory.module.annotation.AgentModule; import work.slhaf.partner.api.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.factory.module.annotation.Before; import work.slhaf.partner.api.factory.module.annotation.BeforeExecute;
import work.slhaf.partner.api.factory.module.annotation.Init;
import work.slhaf.partner.api.factory.module.pojo.MetaMethod; import work.slhaf.partner.api.factory.module.pojo.MetaMethod;
import work.slhaf.partner.api.factory.module.pojo.MetaModule; import work.slhaf.partner.api.factory.module.pojo.MetaModule;
@@ -22,6 +23,7 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
private List<MetaModule> moduleList; private List<MetaModule> moduleList;
private HashMap<Class<?>, Set<MetaMethod>> postHookMethods; private HashMap<Class<?>, Set<MetaMethod>> postHookMethods;
private HashMap<Class<?>, Set<MetaMethod>> preHookMethods; private HashMap<Class<?>, Set<MetaMethod>> preHookMethods;
private HashMap<Class<?>, Set<MetaMethod>> initHookMethods;
@Override @Override
protected void setVariables(AgentRegisterContext context) { protected void setVariables(AgentRegisterContext context) {
@@ -30,6 +32,7 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
moduleList = factoryContext.getModuleList(); moduleList = factoryContext.getModuleList();
postHookMethods = factoryContext.getPostHookMethods(); postHookMethods = factoryContext.getPostHookMethods();
preHookMethods = factoryContext.getPreHookMethods(); preHookMethods = factoryContext.getPreHookMethods();
initHookMethods = factoryContext.getInitHookMethods();
} }
@Override @Override
@@ -41,25 +44,37 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
private void registerHookSet() { private void registerHookSet() {
setPostHookMethods(); setPostHookMethods();
setPreHookMethods(); setPreHookMethods();
setInitMethods();
} }
private void setPreHookMethods() { private void setInitMethods() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(After.class); Set<Method> methods = reflections.getMethodsAnnotatedWith(Init.class);
for (Method method : methods) { for (Method method : methods) {
MetaMethod metaMethod = new MetaMethod(); MetaMethod metaMethod = new MetaMethod();
metaMethod.setMethod(method); metaMethod.setMethod(method);
metaMethod.setOrder(method.getAnnotation(After.class).order()); metaMethod.setOrder(method.getAnnotation(Init.class).order());
addMetaMethod(method, metaMethod, initHookMethods);
}
}
private void setPreHookMethods() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(AfterExecute.class);
for (Method method : methods) {
MetaMethod metaMethod = new MetaMethod();
metaMethod.setMethod(method);
metaMethod.setOrder(method.getAnnotation(AfterExecute.class).order());
addMetaMethod(method, metaMethod, postHookMethods); addMetaMethod(method, metaMethod, postHookMethods);
} }
} }
private void setPostHookMethods() { private void setPostHookMethods() {
Set<Method> methods = reflections.getMethodsAnnotatedWith(Before.class); Set<Method> methods = reflections.getMethodsAnnotatedWith(BeforeExecute.class);
for (Method method : methods) { for (Method method : methods) {
MetaMethod metaMethod = new MetaMethod(); MetaMethod metaMethod = new MetaMethod();
metaMethod.setMethod(method); metaMethod.setMethod(method);
metaMethod.setOrder(method.getAnnotation(Before.class).order()); metaMethod.setOrder(method.getAnnotation(BeforeExecute.class).order());
addMetaMethod(method, metaMethod, preHookMethods); addMetaMethod(method, metaMethod, preHookMethods);
} }

View File

@@ -15,6 +15,6 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface After { public @interface AfterExecute {
int order() default 0; int order() default 0;
} }

View File

@@ -13,6 +13,6 @@ import java.lang.annotation.Target;
*/ */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Before { public @interface BeforeExecute {
int order() default 0; int order() default 0;
} }

View File

@@ -0,0 +1,12 @@
package work.slhaf.partner.api.factory.module.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Init {
int order() default 0;
}

View File

@@ -1,6 +1,9 @@
package work.slhaf.partner.api.flow; package work.slhaf.partner.api.flow;
import work.slhaf.partner.api.entity.AgentContext; import work.slhaf.partner.api.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.flow.entity.InteractionFlowContext;
import java.util.List;
/** /**
* Agent执行流程 * Agent执行流程
@@ -9,7 +12,7 @@ public class AgentInteraction {
private AgentInteraction(){} private AgentInteraction(){}
public static void launch(AgentContext context){ public static void launch(List<MetaModule> moduleList, InteractionFlowContext interactionContext){
//流程执行启动需考虑模块热插拔可结合http调整模块启用情况并序列化至本地或数据库中 //流程执行启动需考虑模块热插拔可结合http调整模块启用情况并序列化至本地或数据库中
} }
} }

View File

@@ -7,14 +7,14 @@ import work.slhaf.partner.api.common.chat.pojo.ChatResponse;
import work.slhaf.partner.api.common.chat.pojo.Message; import work.slhaf.partner.api.common.chat.pojo.Message;
import work.slhaf.partner.api.factory.config.ModelConfigManager; import work.slhaf.partner.api.factory.config.ModelConfigManager;
import work.slhaf.partner.api.factory.config.pojo.ModelConfig; import work.slhaf.partner.api.factory.config.pojo.ModelConfig;
import work.slhaf.partner.api.factory.module.annotation.Before; import work.slhaf.partner.api.factory.module.annotation.BeforeExecute;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public interface ActivateModel { public interface ActivateModel {
@Before @BeforeExecute
default void modelSettings() { default void modelSettings() {
Model model = new Model(); Model model = new Model();
ModelConfig modelConfig = ModelConfigManager.INSTANCE.loadModelConfig(modelKey()); ModelConfig modelConfig = ModelConfigManager.INSTANCE.loadModelConfig(modelKey());

View File

@@ -6,5 +6,6 @@ import lombok.Data;
* 流程上下文 * 流程上下文
*/ */
@Data @Data
public class InteractionFlowContext { public abstract class InteractionFlowContext {
} }

View File

@@ -0,0 +1,7 @@
import work.slhaf.partner.api.Agent;
public class TestApplication {
public static void main(String[] args) {
Agent.newAgent(TestApplication.class,null).run();
}
}

View File

@@ -0,0 +1,24 @@
package module;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import org.junit.jupiter.api.Test;
import work.slhaf.partner.api.flow.abstracts.AgentInteractionModule;
import java.lang.reflect.InvocationTargetException;
public class ModuleProxyTest {
@Test
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<? extends AgentInteractionModule> clazz = new ByteBuddy().subclass(MyAgentInteractionModule.class)
.method(ElementMatchers.isOverriddenFrom(AgentInteractionModule.class))
.intercept(MethodDelegation.to(
new MyModuleProxyInterceptor()
))
.make()
.load(ModuleProxyTest.class.getClassLoader())
.getLoaded();
clazz.getConstructor().newInstance().execute(null);
}
}

View File

@@ -0,0 +1,11 @@
package module;
import work.slhaf.partner.api.flow.abstracts.AgentInteractionModule;
import work.slhaf.partner.api.flow.entity.InteractionFlowContext;
public class MyAgentInteractionModule extends AgentInteractionModule {
@Override
public void execute(InteractionFlowContext context) {
System.out.println("MyAgentInteractionModule");
}
}

View File

@@ -0,0 +1,18 @@
package module;
import net.bytebuddy.implementation.bind.annotation.*;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class MyModuleProxyInterceptor {
public MyModuleProxyInterceptor() {}
@RuntimeType
public Object intercept(@Origin Method method, @AllArguments Object[] allArguments, @SuperCall Callable<?> zuper, @This Object proxy) throws Exception {
System.out.println("22222");
Object res = zuper.call();
System.out.println("11111");
return res;
}
}