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
.gitignore
vendored
1
.gitignore
vendored
@@ -53,3 +53,4 @@ build/
|
||||
/CLAUDE.md
|
||||
/config/
|
||||
/data/
|
||||
/generated-classes/
|
||||
|
||||
11
.idea/misc.xml
generated
11
.idea/misc.xml
generated
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<list size="13">
|
||||
<list size="14">
|
||||
<item index="0" class="java.lang.String" itemvalue="lombok.Data" />
|
||||
<item index="1" class="java.lang.String" itemvalue="net.bytebuddy.implementation.bind.annotation.RuntimeType" />
|
||||
<item index="2" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Capability" />
|
||||
@@ -11,10 +11,11 @@
|
||||
<item index="6" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.capability.annotation.Coordinated" />
|
||||
<item index="7" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute" />
|
||||
<item index="8" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.AgentModule" />
|
||||
<item index="9" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.Init" />
|
||||
<item index="10" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CapabilityMethod" />
|
||||
<item index="11" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CoordinateManager" />
|
||||
<item index="12" class="java.lang.String" itemvalue="work.slhaf.partner.api.register.capability.annotation.Capability" />
|
||||
<item index="9" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute" />
|
||||
<item index="10" class="java.lang.String" itemvalue="work.slhaf.partner.api.agent.factory.module.annotation.Init" />
|
||||
<item index="11" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CapabilityMethod" />
|
||||
<item index="12" class="java.lang.String" itemvalue="work.slhaf.partner.api.capability.annotation.CoordinateManager" />
|
||||
<item index="13" class="java.lang.String" itemvalue="work.slhaf.partner.api.register.capability.annotation.Capability" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
|
||||
@@ -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) {
|
||||
@@ -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,8 +120,14 @@ 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);
|
||||
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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ public class CognationCore extends PersistableObject {
|
||||
} else {
|
||||
FileUtils.createParentDirectories(filePath.toFile().getParentFile());
|
||||
connectCores(this);
|
||||
this.activeData = new ActiveData();
|
||||
this.serialize();
|
||||
}
|
||||
setupHook(this);
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package work.slhaf.partner.core.cognation.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import work.slhaf.partner.api.common.entity.PersistableObject;
|
||||
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class ActiveData {
|
||||
private HashMap<String, List<EvaluatedSlice>> activatedSlices;
|
||||
public class ActiveData extends PersistableObject {
|
||||
private HashMap<String, List<EvaluatedSlice>> activatedSlices = new HashMap<>();
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public void updateActivatedSlices(String userId, List<EvaluatedSlice> memorySlices) {
|
||||
activatedSlices.put(userId, memorySlices);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package work.slhaf.partner.module.common.module;
|
||||
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
|
||||
public abstract class CoreRunningModule extends AgentRunningModule<PartnerRunningFlowContext> {
|
||||
}
|
||||
@@ -3,5 +3,19 @@ package work.slhaf.partner.module.common.module;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class PostRunningModule extends AgentRunningModule<PartnerRunningFlowContext> {
|
||||
|
||||
@Override
|
||||
public final void execute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException {
|
||||
boolean trigger = context.getModuleContext().getExtraContext().getBoolean("post_process_trigger");
|
||||
if (!trigger){
|
||||
return;
|
||||
}
|
||||
doExecute(context);
|
||||
}
|
||||
|
||||
protected void doExecute(PartnerRunningFlowContext context){}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package work.slhaf.partner.module.common.module;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.module.common.entity.AppendPromptData;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
@@ -32,11 +31,9 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
|
||||
|
||||
@Override
|
||||
public final void execute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException {
|
||||
log.debug("[{}] 模块执行开始...", this.getClass().getAnnotation(AgentModule.class).name());
|
||||
doExecute(context); // 子类实现差异化逻辑
|
||||
setAppendedPrompt(context); // 通用逻辑
|
||||
setActiveModule(context); // 通用逻辑
|
||||
log.debug("[{}] 模块执行结束...", this.getClass().getAnnotation(AgentModule.class).name());
|
||||
}
|
||||
|
||||
protected abstract void doExecute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException;
|
||||
|
||||
@@ -8,6 +8,7 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapabili
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.CoreModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.api.chat.constant.ChatConstant;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
@@ -15,7 +16,6 @@ import work.slhaf.partner.api.chat.pojo.MetaMessage;
|
||||
import work.slhaf.partner.core.cognation.CognationCapability;
|
||||
import work.slhaf.partner.module.common.entity.AppendPromptData;
|
||||
import work.slhaf.partner.module.common.model.ModelConstant;
|
||||
import work.slhaf.partner.module.common.module.CoreRunningModule;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
import work.slhaf.partner.runtime.session.SessionManager;
|
||||
|
||||
@@ -30,7 +30,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.extractJson;
|
||||
@Data
|
||||
@Slf4j
|
||||
@CoreModule
|
||||
public class CoreModel extends CoreRunningModule implements ActivateModel {
|
||||
public class CoreModel extends AgentRunningModule<PartnerRunningFlowContext> implements ActivateModel {
|
||||
|
||||
@InjectCapability
|
||||
private CognationCapability cognationCapability;
|
||||
|
||||
@@ -5,7 +5,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
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.InjectModule;
|
||||
import work.slhaf.partner.core.cognation.CognationCapability;
|
||||
@@ -59,6 +58,7 @@ public class MemorySelector extends PreRunningModule {
|
||||
List<EvaluatedSlice> evaluatedSlices = selectAndEvaluateMemory(runningFlowContext, extractorResult);
|
||||
cognationCapability.updateActivatedSlices(userId, evaluatedSlices);
|
||||
}
|
||||
setModuleContextRecall(runningFlowContext);
|
||||
}
|
||||
|
||||
private List<EvaluatedSlice> selectAndEvaluateMemory(PartnerRunningFlowContext runningFlowContext, ExtractorResult extractorResult) throws IOException, ClassNotFoundException {
|
||||
@@ -79,7 +79,6 @@ public class MemorySelector extends PreRunningModule {
|
||||
return memorySlices;
|
||||
}
|
||||
|
||||
@AfterExecute(order = 1)
|
||||
private void setModuleContextRecall(PartnerRunningFlowContext runningFlowContext) {
|
||||
String userId = runningFlowContext.getUserId();
|
||||
boolean recall = cognationCapability.hasActivatedSlices(userId);
|
||||
|
||||
@@ -94,6 +94,9 @@ public class MemorySelectExtractor extends AgentRunningSubModule<PartnerRunningF
|
||||
}
|
||||
m.setText(fixTopicPath(m.getText()));
|
||||
});
|
||||
if (extractorResult.getMatches().isEmpty()) {
|
||||
return extractorResult;
|
||||
}
|
||||
extractorResult.getMatches().removeIf(m -> m.getText().split("->")[0].isEmpty());
|
||||
return extractorResult;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class MemoryUpdater extends PostRunningModule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(PartnerRunningFlowContext context) {
|
||||
public void doExecute(PartnerRunningFlowContext context) {
|
||||
if (context.isFinished()) {
|
||||
log.warn("[MemoryUpdater] 流程强制结束, 不触发记忆被动更新机制");
|
||||
return;
|
||||
|
||||
@@ -7,17 +7,16 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapabili
|
||||
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.factory.module.annotation.InjectModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
|
||||
import work.slhaf.partner.core.cognation.CognationCapability;
|
||||
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability;
|
||||
import work.slhaf.partner.core.submodule.perceive.pojo.User;
|
||||
import work.slhaf.partner.module.common.module.PostRunningModule;
|
||||
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.RelationExtractor;
|
||||
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo.RelationExtractResult;
|
||||
import work.slhaf.partner.module.modules.perceive.updater.static_extractor.StaticMemoryExtractor;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -31,7 +30,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
@Slf4j
|
||||
@Data
|
||||
@AgentModule(name = "perceive_updater", order = 8)
|
||||
public class PerceiveUpdater extends AgentRunningModule<PartnerRunningFlowContext> {
|
||||
public class PerceiveUpdater extends PostRunningModule {
|
||||
|
||||
private static volatile PerceiveUpdater perceiveUpdater;
|
||||
|
||||
@@ -53,12 +52,9 @@ public class PerceiveUpdater extends AgentRunningModule<PartnerRunningFlowContex
|
||||
this.executor = InteractionThreadPoolExecutor.getInstance();
|
||||
}
|
||||
|
||||
public void execute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException {
|
||||
@Override
|
||||
public void doExecute(PartnerRunningFlowContext context) {
|
||||
executor.execute(() -> {
|
||||
boolean trigger = context.getModuleContext().getExtraContext().getBoolean("perceive_updater");
|
||||
if (!trigger){
|
||||
return;
|
||||
}
|
||||
ReentrantLock userLock = new ReentrantLock();
|
||||
User user = new User();
|
||||
user.setUuid(context.getUserId());
|
||||
|
||||
@@ -5,8 +5,8 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.core.cognation.CognationCapability;
|
||||
import work.slhaf.partner.module.common.module.PostRunningModule;
|
||||
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -15,7 +15,7 @@ import java.io.IOException;
|
||||
@Slf4j
|
||||
@Data
|
||||
@AgentModule(name = "postprocess_executor", order = 6)
|
||||
public class PostprocessExecutor extends PostRunningModule {
|
||||
public class PostprocessExecutor extends AgentRunningModule<PartnerRunningFlowContext> {
|
||||
|
||||
private static final int POST_PROCESS_TRIGGER_ROLL_LIMIT = 36;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package work.slhaf.partner.module.modules.process;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityHolder;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.core.cognation.CognationCapability;
|
||||
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability;
|
||||
@@ -17,9 +18,10 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
@CapabilityHolder
|
||||
@AgentModule(name = "preprocess_executor", order = 1)
|
||||
public class PreprocessExecutor extends PreRunningModule {
|
||||
|
||||
private static volatile PreprocessExecutor preprocessExecutor;
|
||||
|
||||
@@ -38,6 +38,7 @@ public class WebSocketGateway extends WebSocketServer implements AgentGateway<Pa
|
||||
|
||||
private WebSocketGateway(int port) {
|
||||
super(new InetSocketAddress(port));
|
||||
this.setReuseAddr(true);
|
||||
this.executor = InteractionThreadPoolExecutor.getInstance();
|
||||
}
|
||||
|
||||
@@ -101,15 +102,29 @@ public class WebSocketGateway extends WebSocketServer implements AgentGateway<Pa
|
||||
}
|
||||
|
||||
private void setShutDownHook() {
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
//关闭WebSocketServer
|
||||
this.stop();
|
||||
// 先断开所有客户端连接
|
||||
for (WebSocket webSocket : getConnections()) {
|
||||
try {
|
||||
webSocket.close(1001, "Server shutting down");
|
||||
} catch (Exception e) {
|
||||
log.warn("关闭客户端连接时出错: ", e);
|
||||
}
|
||||
}
|
||||
//关闭WebSocketServer,给10秒超时时间确保连接正确关闭
|
||||
this.stop(10000);
|
||||
log.info("WebSocketServer 已关闭");
|
||||
} catch (IllegalStateException e) {
|
||||
log.warn("无法添加关闭钩子,JVM可能已在关闭过程中: ", e);
|
||||
} catch (Exception e) {
|
||||
log.error("WebSocketServer关闭失败: ", e);
|
||||
}
|
||||
}));
|
||||
} catch (IllegalStateException e) {
|
||||
log.warn("无法添加关闭钩子,JVM可能已在关闭过程中: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
14
README.md
14
README.md
@@ -47,35 +47,35 @@ Partner 的目标不是复现某种单一能力,而是尝试在结构中形成
|
||||
## 模块(已实现/正在实现)
|
||||
- 预处理模块: `PreprocessExecutor`
|
||||
- 后处理模块: `PostprocessExecutor`
|
||||
- 主对话模块: `CoreModel`
|
||||
- 记忆模块
|
||||
- 记忆选择模块: `MemorySelector`
|
||||
- 主题提取模块: `MemorySelectExtractor`
|
||||
- 切片评估模块: `SliceSelectEvaluator`
|
||||
- 记忆更新模块: `MemoryUpdater`
|
||||
- 记忆总结模块: `MemorySummarizer`
|
||||
- 静态记忆提取模块: `StaticMemoryExtractor`
|
||||
- 记忆总结模块[多聊天对象]: `MultiSummarizer`
|
||||
- 记忆总结模块[单聊天对象]: `SingleSummarizer`
|
||||
- 记忆总结模块[汇总]:`TotalSummarizer`
|
||||
- 感知模块
|
||||
- 感知选择模块: `PerceiveSelector`
|
||||
- 感知更新模块: `PerceiveUpdater`
|
||||
- 关系提取模块: `RelationExtractor`
|
||||
- 静态记忆提取模块: `StaticExtractor`
|
||||
- 任务调度模块
|
||||
- 静态记忆提取模块: `StaticMemoryExtractor`
|
||||
- 任务调度模块(待实现)
|
||||
- 任务评估模块: `TaskEvaluator`
|
||||
- 任务执行模块: `TaskExecutor`
|
||||
- 任务规划模块: `TaskScheduler`
|
||||
- 主对话模块: `CoreModel`
|
||||
|
||||
## 当前问题
|
||||
- 系统的正常运作效果取决于各模块中大模型对于`prompt`的遵循能力,目前来看`qwen3`的遵循效果明显较好,但在轮次较多时,也容易出现不遵循的情况。
|
||||
|
||||
## 规划
|
||||
- [ ] 完成框架与本体的适配工作
|
||||
- [ ] 实现任务与主动调度模块,目前打算用 `时间轮算法` 实现定时操作
|
||||
- [ ] 完善具备‘记忆切片、实体图谱、向量召回’的三维记忆融合架构,包含 Episodic + Semantic + Fuzzy 三类记忆
|
||||
- [ ] 服务端与客户端的通信加上消息队列,防止消息因连接断开而丢失。
|
||||
- [ ] 实现流式输出,同时在各模块执行时可向客户端返回回调信息,优化使用体验。(现在用的是`websocket`与客户端通信, 应该实现这点会简单些)
|
||||
- [ ] 踩坑。
|
||||
- [ ] 实现角色演进机制
|
||||
- [ ] 实现演进机制
|
||||
|
||||
## License
|
||||
This project is not licensed for public use. All rights reserved.
|
||||
|
||||
Reference in New Issue
Block a user