开始推进行动模块(ActionModule); 针对框架与本体分别进行了一系列架构优化。

框架:
- 调整模块注册以及AgentRunningFlow的相关逻辑,以支持同组模块并发执行,将以@AgentModule注解中的order属性区分组间顺序先后及是否同组
- 针对@CoordinateManager注解新增了Core的自动注入处理,以便更好的协调不同Core的逻辑

本体: - 开始推进行动模块。将采取类似记忆模块的分层思路,分为ActionPlanner与ActionDispatcher两个主要模块,再各自细分子模块划分
- 将CognationCore从核心统筹的身份下降至与其他核心平级,同时将其中的序列化逻辑抽取至统一的PartnerCore父类,所有核心都将继承该类以获得序列化能力,不同core的内容将序列化至各自的memory文件
- 将SessionManager移除,相关逻辑迁移至CognationCore,统一序列化逻辑的同时又保证语义正确
- 将CognationCore中的某些缓存性质逻辑移动至CacheCore,确保语义正确
- 调整了目录结构以适应优化过的架构
This commit is contained in:
2025-10-12 16:23:11 +08:00
parent 41bf19f43e
commit a10a149edb
94 changed files with 1021 additions and 793 deletions

View File

@@ -13,6 +13,7 @@ import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -99,7 +100,7 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
}
Object o = constructor.newInstance();
capabilityHolderInstances.put(clazz, o);
}catch (Exception e){
} catch (Exception e) {
throw new CapabilityFactoryExecuteFailedException("创建代理对象失败: " + clazz, e);
}
}
@@ -149,7 +150,7 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
for (Class<?> c : reflections.getTypesAnnotatedWith(CoordinateManager.class)) {
Constructor<?> constructor = c.getDeclaredConstructor();
Object instance = constructor.newInstance();
setCores(instance, c);
Arrays.stream(c.getMethods())
.filter(method -> method.isAnnotationPresent(Coordinated.class))
.forEach(method -> {
@@ -160,6 +161,15 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
return map;
}
private void setCores(Object cmInstance, Class<?> cmClazz) throws IllegalAccessException {
for (Field field : cmClazz.getFields()) {
if (field.getType().isAnnotationPresent(CapabilityCore.class)) {
field.setAccessible(true);
field.set(cmInstance, coreInstances.get(field.getType()));
}
}
}
/**
* 扫描`@Capability`与`@CapabilityMethod`注解的类与方法
* 将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法

View File

@@ -5,6 +5,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Core的协调类该注解的实现类中如果存在任何{@link CapabilityCore}实例的引用,都将被自动注入
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CoordinateManager {

View File

@@ -9,8 +9,7 @@ import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
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.List;
import java.util.*;
@Slf4j
@Data
@@ -23,7 +22,8 @@ public abstract class AgentConfigManager {
protected HashMap<String, ModelConfig> modelConfigMap;
protected HashMap<String, List<Message>> modelPromptMap;
protected HashMap<String, Boolean> moduleEnabledStatus;
protected List<MetaModule> moduleList;
protected Map<Integer, List<MetaModule>> moduleOrderedMap = new LinkedHashMap<>();
protected Map<String, MetaModule> moduleMap = new HashMap<>();
public void load() {
modelConfigMap = loadModelConfig();
@@ -38,11 +38,24 @@ public abstract class AgentConfigManager {
protected abstract void dumpModuleEnabledStatus();
protected abstract HashMap<String, Boolean> loadModuleEnabledStatusMap();
protected abstract HashMap<String, Boolean> loadModuleEnabledStatusMap(List<MetaModule> moduleList);
public void moduleEnabledStatusFilterAndRecord(List<MetaModule> moduleList) {
this.moduleList = moduleList;
this.moduleEnabledStatus = loadModuleEnabledStatusMap();
updateModuleMap(moduleList);
updateModuleEnabledStatus(moduleList);
}
private void updateModuleMap(List<MetaModule> moduleList) {
//在ModuleRegisterFactory已进行过排序操作
for (MetaModule module : moduleList) {
int k = module.getOrder();
moduleOrderedMap.computeIfAbsent(k, order -> new ArrayList<>()).add(module);
moduleMap.put(module.getName(), module);
}
}
private void updateModuleEnabledStatus(List<MetaModule> moduleList) {
this.moduleEnabledStatus = loadModuleEnabledStatusMap(moduleList);
boolean unmatch = false;
for (MetaModule metaModule : moduleList) {
@@ -84,12 +97,7 @@ public abstract class AgentConfigManager {
}
moduleEnabledStatus.put(key, status);
dumpModuleEnabledStatus();
for (MetaModule metaModule : moduleList) {
if (metaModule.getName().equals(key)) {
metaModule.setEnabled(status);
break;
}
}
moduleMap.get(key).setEnabled(status);
}
}

View File

@@ -74,7 +74,7 @@ public class FileAgentConfigManager extends AgentConfigManager {
}
@Override
protected HashMap<String, Boolean> loadModuleEnabledStatusMap() {
protected HashMap<String, Boolean> loadModuleEnabledStatusMap(List<MetaModule> moduleList) {
File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE);
try {
moduleEnabledStatus = new HashMap<>();

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.agent.runtime.exception;
public class AgentRunningFailedException extends AgentRuntimeException{
public AgentRunningFailedException(String message) {
super(message);
}
public AgentRunningFailedException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -9,18 +9,28 @@ public class GlobalExceptionHandler {
private AgentExceptionCallback exceptionCallback = new LogAgentExceptionCallback();
public void handle(Throwable e) {
switch (e.getClass().getSimpleName()) {
case "AgentRuntimeException":
exceptionCallback.onRuntimeException((AgentRuntimeException) e);
break;
case "AgentLaunchFailedException":
exceptionCallback.onFailedException((AgentLaunchFailedException) e);
break;
default:
log.error("未知异常: ", e);
public boolean handle(Throwable e) {
boolean exit;
Throwable cause = e.getCause();
switch (cause) {
case AgentRunningFailedException arfe -> {
exit = true;
exceptionCallback.onRuntimeException((AgentRuntimeException) cause);
}
case AgentRuntimeException are -> {
exit = false;
exceptionCallback.onRuntimeException((AgentRuntimeException) cause);
}
case AgentLaunchFailedException alfe -> {
exit = true;
exceptionCallback.onFailedException((AgentLaunchFailedException) cause);
}
default -> {
exit = true;
log.error("意外异常: ", cause);
}
}
return exit;
}
public static void setExceptionCallback(AgentExceptionCallback callback) {

View File

@@ -8,14 +8,15 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.AgentRunningFlow;
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext;
import java.util.List;
import java.util.Map;
public abstract class AgentInteractionAdapter<I extends AgentInputData, O extends AgentOutputData, C extends RunningFlowContext> {
protected AgentRunningFlow<C> agentRunningFlow = new AgentRunningFlow<>();
protected List<MetaModule> moduleList = AgentConfigManager.INSTANCE.getModuleList();
protected Map<Integer, List<MetaModule>> moduleOrderedMap = AgentConfigManager.INSTANCE.getModuleOrderedMap();
public C call(C finalInputData){
return agentRunningFlow.launch(moduleList, finalInputData);
return agentRunningFlow.launch(moduleOrderedMap, finalInputData);
}
protected abstract O parseOutputData(C outputContext);

View File

@@ -1,27 +1,52 @@
package work.slhaf.partner.api.agent.runtime.interaction.flow;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException;
import work.slhaf.partner.api.agent.runtime.exception.GlobalExceptionHandler;
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Agent执行流程
*/
public class AgentRunningFlow<C extends RunningFlowContext> {
public C launch(List<MetaModule> moduleList, C interactionContext){
try {
public C launch(Map<Integer, List<MetaModule>> modules, C interactionContext) {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
//流程执行启动
for (MetaModule metaModule : moduleList) {
metaModule.getInstance().execute(interactionContext);
for (Map.Entry<Integer, List<MetaModule>> entry : modules.entrySet()) {
List<Future<?>> futures = new ArrayList<>();
List<MetaModule> moduleList = entry.getValue();
for (MetaModule module : moduleList) {
Future<?> future = executor.submit(() -> {
try {
module.getInstance().execute(interactionContext);
} catch (Exception e) {
throw new AgentRuntimeException("模块执行出错: " + module.getName(), e);
}
});
futures.add(future);
}
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
boolean exit = GlobalExceptionHandler.INSTANCE.handle(e);
if (exit) throw new AgentRuntimeException("Agent执行出错!", e);
interactionContext.getErrMsg().add(e.getLocalizedMessage());
}
}
}
interactionContext.setOk(1);
}catch (Exception e){
GlobalExceptionHandler.INSTANCE.handle(e);
} catch (Exception e) {
interactionContext.setOk(0);
interactionContext.setErrMsg(e.getMessage());
interactionContext.getErrMsg().add(e.getLocalizedMessage());
}
return interactionContext;
}

View File

@@ -87,6 +87,9 @@ public interface ActivateModel {
((Module) this).setModel(model);
}
/**
* 对应调用的模型配置名称
*/
String modelKey();
boolean withBasicPrompt();

View File

@@ -4,6 +4,9 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.common.entity.PersistableObject;
import java.util.ArrayList;
import java.util.List;
/**
* 流程上下文
*/
@@ -11,5 +14,5 @@ import work.slhaf.partner.api.common.entity.PersistableObject;
@Data
public abstract class RunningFlowContext extends PersistableObject {
protected int ok;
protected String errMsg;
protected List<String> errMsg = new ArrayList<>();
}

View File

@@ -6,11 +6,12 @@ import net.bytebuddy.matcher.ElementMatchers;
import org.junit.jupiter.api.Test;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
public class ModuleProxyTest {
@Test
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
Class<? extends AgentRunningModule> clazz = new ByteBuddy().subclass(MyAgentRunningModule.class)
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
.intercept(MethodDelegation.to(