mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
Partner 主体与框架适配完成! 完整逻辑已达到适配框架之前的完成度。发现并修复了不少问题,以及更新了README
框架: - 由于`Gateway`的启动属于`Agent`启动流程的子线程,而主线程可能由于逻辑执行结束时机早于`Gateway`创建完成时机而报错,故引入`CountDownLatch`进行阻塞 - 在`AgentRunningModule`与`AgentRunningSubModule`中添加日志hook,记录模块执行的起始与截止时机 - 修复了`AgentUtil`中收集继承链时遗忘起始类的错误 - 在`CapabilityCheckFactory`中针对`CoordinateManager`无参构造方法的实现检验 - 在`CapabilityRegisterFactory`中添加了收集模块之外的CapabilityHolder的逻辑,与`@InjectCapability`的校验与注入逻辑保持一致 - 修复了‘生成模块启用配置时,多余局部变量导致无法执行流正确读取启用情况’的错误 - 在GlobalExceptionHandler中添加了对于未知异常的处理逻辑,确保不会导致程序异常终止 - 发现`ModuleProxyFactory`中使用`record`类型会导致`ByteBuddy`无法正确创建代理类,已修复,替换成普通类 本体: - `ActiveData`由于`CognationCore`的引用,也需要实现序列化,已修复 - 修复了`MemorySelectExtractor`中由于匹配到的主题列表为空导致的空指针异常 - 将后置模块的trigger判定抽取到新的父类中,统一判断 - 修复了`WebSocketServer`如果存在过ws连接,关闭后短时间再次启动内仍提示端口占用的情况,设置允许端口重用 - 在`WebSocketGateway`新增了断开ws客户端连接的逻辑
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package work.slhaf.partner.api.agent;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.AgentRegisterFactory;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentExceptionCallback;
|
||||
@@ -9,6 +10,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.AgentGateway;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -16,6 +18,7 @@ import java.util.concurrent.Executors;
|
||||
* <h2>Agent 启动入口</h2>
|
||||
* 详细启动流程请参阅{@link AgentRegisterFactory}
|
||||
*/
|
||||
@Slf4j
|
||||
public final class Agent {
|
||||
|
||||
public static AgentConfigManagerStep newAgent(Class<?> clazz) {
|
||||
@@ -38,7 +41,7 @@ public final class Agent {
|
||||
|
||||
AgentStep addAfterLaunchRunners(Runnable... runners);
|
||||
|
||||
AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback);
|
||||
AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback);
|
||||
|
||||
AgentStep addScanPackage(String packageName);
|
||||
|
||||
@@ -59,6 +62,8 @@ public final class Agent {
|
||||
private Class<? extends AgentGateway> gatewayClass;
|
||||
private Class<? extends AgentExceptionCallback> agentExceptionCallbackClass;
|
||||
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
private AgentApp(Class<?> clazz) {
|
||||
this.applicationClass = clazz;
|
||||
}
|
||||
@@ -115,9 +120,15 @@ public final class Agent {
|
||||
private void afterLaunch() {
|
||||
try {
|
||||
this.gateway = gatewayClass.getDeclaredConstructor().newInstance();
|
||||
executorService.execute(() -> gateway.launch());
|
||||
executorService.execute(() -> {
|
||||
gateway.launch();
|
||||
latch.countDown();
|
||||
log.info("Gateway 启动完毕: {}", gatewayClass.getSimpleName());
|
||||
});
|
||||
latch.await();
|
||||
launchRunners(afterLaunchRunners);
|
||||
}catch (Exception e){
|
||||
log.info("后置任务启动完毕");
|
||||
} catch (Exception e) {
|
||||
throw new AgentLaunchFailedException("Agent 后置任务启动失败", e);
|
||||
}
|
||||
}
|
||||
@@ -125,8 +136,11 @@ public final class Agent {
|
||||
private void beforeLaunch() {
|
||||
try {
|
||||
AgentConfigManager.setINSTANCE(agentConfigManagerClass.getDeclaredConstructor().newInstance());
|
||||
log.info("配置管理器设置完毕: {}",agentConfigManagerClass.getSimpleName());
|
||||
GlobalExceptionHandler.setExceptionCallback(agentExceptionCallbackClass.getDeclaredConstructor().newInstance());
|
||||
log.info("异常处理回调设置完毕: {}",agentExceptionCallbackClass.getSimpleName());
|
||||
launchRunners(beforeLaunchRunners);
|
||||
log.info("前置任务启动完毕");
|
||||
} catch (Exception e) {
|
||||
throw new AgentLaunchFailedException("Agent 前置任务启动失败", e);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package work.slhaf.partner.api.agent.factory.capability;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import org.reflections.Reflections;
|
||||
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.*;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.DuplicateCapabilityException;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.UnMatchedCapabilityException;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.UnMatchedCapabilityMethodException;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.UnMatchedCoordinatedMethodException;
|
||||
import work.slhaf.partner.api.agent.factory.capability.exception.*;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.CapabilityFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
@@ -67,14 +65,29 @@ public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
//TODO 对于CoordinateManager的所注类进行唯一性检验以及检测是否留有公开的无参构造方法
|
||||
loadCoresAndCapabilities();
|
||||
checkCountAndCapabilities();
|
||||
checkCapabilityMethods();
|
||||
checkCoordinatedMethods();
|
||||
checkCoordinatedManager();
|
||||
checkInjectCapability();
|
||||
}
|
||||
|
||||
private void checkCoordinatedManager() {
|
||||
reflections.getTypesAnnotatedWith(CoordinateManager.class)
|
||||
.stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.forEach(managerClass -> {
|
||||
try {
|
||||
if (!managerClass.getDeclaredConstructor().canAccess(null)) {
|
||||
throw new CapabilityCheckFailedException("CoordinateManager 所注类的无参构造方法未公开!");
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new CapabilityCheckFailedException("CoordinateManager 所注类缺少无参构造方法!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadCoresAndCapabilities() {
|
||||
cores.addAll(reflections.getTypesAnnotatedWith(CapabilityCore.class));
|
||||
capabilities.addAll(reflections.getTypesAnnotatedWith(Capability.class));
|
||||
@@ -86,8 +99,8 @@ public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
private void checkInjectCapability() {
|
||||
reflections.getFieldsAnnotatedWith(InjectCapability.class).forEach(field -> {
|
||||
Class<?> declaringClass = field.getDeclaringClass();
|
||||
if (!isAssignableFromAnnotation(declaringClass, CapabilityHolder.class)){
|
||||
throw new UnMatchedCapabilityException("InjectCapability 注解只能用于 CapabilityHolder 注解所在类,检查该类是否使用了@CapabilityHolder注解或者受其标注的注解或父类: "+declaringClass);
|
||||
if (!isAssignableFromAnnotation(declaringClass, CapabilityHolder.class)) {
|
||||
throw new UnMatchedCapabilityException("InjectCapability 注解只能用于 CapabilityHolder 注解所在类,检查该类是否使用了@CapabilityHolder注解或者受其标注的注解或父类: " + declaringClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.capability;
|
||||
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import org.reflections.Reflections;
|
||||
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.*;
|
||||
@@ -18,6 +19,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
@@ -79,10 +81,30 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
setCapabilityHolderInstances();
|
||||
setCoreInstances();
|
||||
generateRouterTable();
|
||||
}
|
||||
|
||||
private void setCapabilityHolderInstances() {
|
||||
Set<Class<?>> collect = reflections.getTypesAnnotatedWith(CapabilityHolder.class).stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.filter(clazz -> !capabilityHolderInstances.containsKey(clazz))
|
||||
.collect(Collectors.toSet());
|
||||
for (Class<?> clazz : collect) {
|
||||
try {
|
||||
Constructor<?> constructor = clazz.getDeclaredConstructor();
|
||||
if (constructor.canAccess(null)) {
|
||||
throw new CapabilityFactoryExecuteFailedException("缺少无参构造方法的类: " + clazz);
|
||||
}
|
||||
Object o = constructor.newInstance();
|
||||
capabilityHolderInstances.put(clazz, o);
|
||||
}catch (Exception e){
|
||||
throw new CapabilityFactoryExecuteFailedException("创建代理对象失败: " + clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成函数路由表
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
* 对模型Config与Prompt分别进行检验,除了都必须包含default外,还需要确保数量、key一致,毕竟是模型配置与提示词
|
||||
*/
|
||||
private void check() {
|
||||
log.info("[ConfigLoaderFactory]: 执行config与prompt检测...");
|
||||
log.info("执行config与prompt检测...");
|
||||
if (!modelConfigMap.containsKey("default")) {
|
||||
throw new ConfigNotExistException("缺少默认配置! 需确保存在一个模型配置的key为`default`");
|
||||
}
|
||||
@@ -72,7 +72,6 @@ public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
log.warn("存在未被提示词包含的模型配置,该配置将无法生效!");
|
||||
}
|
||||
//检查提示词数量与`ActivateModel`的实现数量是否一致
|
||||
|
||||
log.info("[ConfigLoaderFactory]: 检测完毕.");
|
||||
log.info("检测完毕.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
moduleConstructorsCheck(annotatedModules.subModuleTypes());
|
||||
//检查实现了ActivateModel的模块数量、名称与prompt是否一致
|
||||
activateModelImplCheck();
|
||||
//检查hook注解所在位置是否正确
|
||||
hookLocationCheck();
|
||||
}
|
||||
|
||||
private ExtendedModules getExtendedModules() {
|
||||
@@ -128,17 +130,6 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
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() {
|
||||
|
||||
@@ -11,6 +11,8 @@ import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.Module;
|
||||
import work.slhaf.partner.api.agent.util.AgentUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -30,7 +32,7 @@ import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* <p>{@link ModuleInitHookExecuteFactory#collectInitHookMethods(Class)}</p>
|
||||
* <p>{@link ModuleInitHookExecuteFactory#collectInitHookMethods(Class, Class)}</p>
|
||||
* 分别遍历前置模块拿到的模块列表({@link ModuleInitHookExecuteFactory#moduleList}, {@link ModuleInitHookExecuteFactory#subModuleList}),通过 {@link AgentUtil#collectExtendedClasses(Class, Class)} 收集到当前模块类的继承链上的所有类后,收集其所有带有 {@link Init} 注解的方法
|
||||
* </li>
|
||||
* <li>
|
||||
@@ -57,12 +59,12 @@ public class ModuleInitHookExecuteFactory extends AgentBaseFactory {
|
||||
protected void run() {
|
||||
//遍历模块列表,并向上查找@Init注解
|
||||
for (MetaSubModule metaSubModule : subModuleList) {
|
||||
List<MetaMethod> initHookMethods = collectInitHookMethods(metaSubModule.getClazz());
|
||||
List<MetaMethod> initHookMethods = collectInitHookMethods(metaSubModule.getClazz(),AgentRunningModule.class);
|
||||
proceedInitMethods(metaSubModule, initHookMethods);
|
||||
}
|
||||
|
||||
for (MetaModule metaModule : moduleList) {
|
||||
List<MetaMethod> initHookMethods = collectInitHookMethods(metaModule.getClazz());
|
||||
List<MetaMethod> initHookMethods = collectInitHookMethods(metaModule.getClazz(), AgentRunningSubModule.class);
|
||||
proceedInitMethods(metaModule, initHookMethods);
|
||||
}
|
||||
}
|
||||
@@ -77,8 +79,8 @@ public class ModuleInitHookExecuteFactory extends AgentBaseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private List<MetaMethod> collectInitHookMethods(Class<?> clazz) {
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, AgentRunningModule.class);
|
||||
private List<MetaMethod> collectInitHookMethods(Class<?> clazz, Class<? extends Module> target) {
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, target);
|
||||
return classes.stream()
|
||||
.map(Class::getDeclaredMethods)
|
||||
.flatMap(Arrays::stream)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.module;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.implementation.MethodDelegation;
|
||||
import net.bytebuddy.implementation.bind.annotation.*;
|
||||
@@ -14,11 +15,13 @@ import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleInstanceGenerateFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleProxyGenerateFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ProxiedModuleRunningException;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.BaseMetaModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.Module;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -74,7 +77,8 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
|
||||
private void injectSubModule() {
|
||||
for (MetaModule module : moduleList) {
|
||||
Arrays.stream(module.getClazz().getFields())
|
||||
//因为实际上ByteBuddy生成的是module.getClazz()的子类,所以应当使用getDeclaredFields()获取字段
|
||||
Arrays.stream(module.getClazz().getDeclaredFields())
|
||||
.filter(field -> field.isAnnotationPresent(InjectModule.class))
|
||||
.forEach(field -> {
|
||||
try {
|
||||
@@ -92,15 +96,14 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
private void createProxiedInstances() {
|
||||
generateModuleProxy(moduleList);
|
||||
generateModuleProxy(subModuleList);
|
||||
generateModuleProxy(moduleList, AgentRunningModule.class);
|
||||
generateModuleProxy(subModuleList, AgentRunningSubModule.class);
|
||||
updateInstanceMap(moduleInstances, moduleList);
|
||||
updateInstanceMap(subModuleInstances, subModuleList);
|
||||
updateCapabilityHolderInstances();
|
||||
}
|
||||
|
||||
private void updateCapabilityHolderInstances() {
|
||||
//TODO 扫描并添加所有与@CapabilityHolder相关的实例
|
||||
capabilityHolderInstances.putAll(moduleInstances);
|
||||
capabilityHolderInstances.putAll(subModuleInstances);
|
||||
}
|
||||
@@ -112,29 +115,38 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
|
||||
private void generateModuleProxy(List<? extends BaseMetaModule> list) {
|
||||
private void generateModuleProxy(List<? extends BaseMetaModule> list, Class<? extends Module> overrideSource) {
|
||||
for (BaseMetaModule module : list) {
|
||||
Class<?> clazz = module.getClazz();
|
||||
try {
|
||||
MethodsListRecord record = collectHookMethods(clazz);
|
||||
//生成实例
|
||||
generateProxiedInstances(record, module);
|
||||
generateProxiedInstances(record, module, overrideSource);
|
||||
} catch (Exception e) {
|
||||
throw new ModuleProxyGenerateFailedException("创建代理对象失败: " + clazz.getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateProxiedInstances(MethodsListRecord record, BaseMetaModule module) {
|
||||
private void generateProxiedInstances(MethodsListRecord record, BaseMetaModule module, Class<? extends Module> overrideSource) {
|
||||
try {
|
||||
Class<? extends Module> clazz = module.getClazz();
|
||||
Class<? extends Module> proxyClass = new ByteBuddy()
|
||||
.subclass(clazz)
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
|
||||
.method(ElementMatchers.isOverriddenFrom(overrideSource))
|
||||
.intercept(MethodDelegation.to(new ModuleProxyInterceptor(record.post, record.pre)))
|
||||
.make()
|
||||
.load(ModuleProxyFactory.class.getClassLoader())
|
||||
.getLoaded();
|
||||
|
||||
// new ByteBuddy()
|
||||
// .subclass(clazz)
|
||||
// .method(ElementMatchers.isOverriddenFrom(overrideSource))
|
||||
// .intercept(MethodDelegation.to(new ModuleProxyInterceptor(record.post, record.pre)))
|
||||
//
|
||||
// .make()
|
||||
// .saveIn(new File("./generated-classes"));
|
||||
|
||||
module.setInstance(proxyClass.getConstructor().newInstance());
|
||||
} catch (Exception e) {
|
||||
throw new ModuleProxyGenerateFailedException("模块Hook代理生成失败! 代理失败的模块名: " + module.getClazz().getSimpleName(), e);
|
||||
@@ -188,7 +200,7 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
|
||||
|
||||
private void collectHookMethods(List<MetaMethod> post, List<MetaMethod> pre, Class<?> clazz) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.isAnnotationPresent(BeforeExecute.class)) {
|
||||
MetaMethod metaMethod = new MetaMethod();
|
||||
@@ -204,18 +216,38 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public record ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
|
||||
@Getter
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public static class ModuleProxyInterceptor {
|
||||
|
||||
private final List<MetaMethod> postHookMethods;
|
||||
private final List<MetaMethod> preHookMethods;
|
||||
|
||||
public ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
|
||||
this.postHookMethods = postHookMethods;
|
||||
this.preHookMethods = preHookMethods;
|
||||
}
|
||||
|
||||
@RuntimeType
|
||||
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);
|
||||
}
|
||||
executeHookMethods(preHookMethods, proxy);
|
||||
Object res = zuper.call();
|
||||
for (MetaMethod metaMethod : postHookMethods) {
|
||||
metaMethod.getMethod().invoke(proxy);
|
||||
}
|
||||
executeHookMethods(postHookMethods, proxy);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void executeHookMethods(List<MetaMethod> hookMethods, Object proxy) {
|
||||
for (MetaMethod metaMethod : hookMethods) {
|
||||
Method m = metaMethod.getMethod();
|
||||
try {
|
||||
m.setAccessible(true);
|
||||
m.invoke(proxy);
|
||||
} catch (Exception e) {
|
||||
throw new ProxiedModuleRunningException("hook方法执行异常: " + m.getDeclaringClass() + "#" + m.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
record MethodsListRecord(List<MetaMethod> post, List<MetaMethod> pre) {
|
||||
|
||||
@@ -3,10 +3,7 @@ package work.slhaf.partner.api.agent.factory.module.annotation;
|
||||
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityHolder;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 用于注解执行模块
|
||||
@@ -14,6 +11,7 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@CapabilityHolder
|
||||
@Inherited
|
||||
public @interface AgentModule {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException;
|
||||
|
||||
public class ProxiedModuleRunningException extends AgentRuntimeException {
|
||||
public ProxiedModuleRunningException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ProxiedModuleRunningException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package work.slhaf.partner.api.agent.runtime.config;
|
||||
import lombok.Data;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ConfigNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ConfigUpdateFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.PromptNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
@@ -11,9 +10,7 @@ import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
|
||||
@@ -77,7 +77,7 @@ public class FileAgentConfigManager extends AgentConfigManager {
|
||||
protected HashMap<String, Boolean> loadModuleEnabledStatusMap() {
|
||||
File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE);
|
||||
try {
|
||||
HashMap<String, Boolean> moduleEnabledStatus = new HashMap<>();
|
||||
moduleEnabledStatus = new HashMap<>();
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
for (MetaModule module : moduleList) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
public static GlobalExceptionHandler INSTANCE = new GlobalExceptionHandler();
|
||||
@@ -16,7 +19,7 @@ public class GlobalExceptionHandler {
|
||||
exceptionCallback.onFailedException((AgentLaunchFailedException) e);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("未经处理的异常!", e);
|
||||
log.error("未知异常: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.Model;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.CoreModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -7,6 +12,27 @@ import java.io.IOException;
|
||||
/**
|
||||
* 流程执行模块基类
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AgentRunningModule<C extends RunningFlowContext> extends Module {
|
||||
public abstract void execute(C context) throws IOException, ClassNotFoundException;
|
||||
|
||||
@BeforeExecute
|
||||
private void beforeLog() {
|
||||
log.debug("[{}] 模块执行开始...", getModuleName());
|
||||
}
|
||||
|
||||
@AfterExecute
|
||||
private void afterLog() {
|
||||
log.debug("[{}] 模块执行结束...", getModuleName());
|
||||
}
|
||||
|
||||
private String getModuleName(){
|
||||
if (this.getClass().isAnnotationPresent(AgentModule.class)) {
|
||||
return this.getClass().getAnnotation(AgentModule.class).name();
|
||||
} else if (this.getClass().isAnnotationPresent(CoreModule.class)) {
|
||||
return CoreModule.class.getAnnotation(AgentModule.class).name();
|
||||
}else {
|
||||
return "Unknown Module";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,35 @@
|
||||
package work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.CoreModule;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AgentRunningSubModule<I, O> extends Module {
|
||||
|
||||
public abstract O execute(I data);
|
||||
|
||||
|
||||
@BeforeExecute
|
||||
private void beforeLog() {
|
||||
log.debug("[{}] 模块执行开始...", getModuleName());
|
||||
}
|
||||
|
||||
@AfterExecute
|
||||
private void afterLog() {
|
||||
log.debug("[{}] 模块执行结束...", getModuleName());
|
||||
}
|
||||
|
||||
private String getModuleName(){
|
||||
if (this.getClass().isAnnotationPresent(AgentModule.class)) {
|
||||
return this.getClass().getAnnotation(AgentModule.class).name();
|
||||
} else if (this.getClass().isAnnotationPresent(CoreModule.class)) {
|
||||
return CoreModule.class.getAnnotation(AgentModule.class).name();
|
||||
}else {
|
||||
return "Unknown Module";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public final class AgentUtil {
|
||||
public static Set<Class<?>> collectExtendedClasses(Class<?> clazz, Class<?> targetClass) {
|
||||
Set<Class<?>> classes = new HashSet<>();
|
||||
collectExtendedClasses(classes, clazz, targetClass);
|
||||
classes.add(clazz);
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user